inheritance c
Importanza dell'ereditarietà in C ++ con esempi:
L'ereditarietà è una delle caratteristiche più importanti della programmazione orientata agli oggetti.
L'ereditarietà è la tecnica con cui una classe acquisisce le proprietà e i metodi di un'altra classe. In questo modo possiamo riutilizzare il codice già scritto e verificato. La classe che acquisisce le proprietà di un'altra classe è chiamata sottoclasse o classe derivata o classe figlia.
La classe le cui proprietà vengono acquisite è chiamata classe base o classe genitore o superclasse. Quando una classe acquisisce o eredita un'altra classe, tutte le proprietà ei metodi della classe base sono disponibili per la classe derivata, in modo da poter riutilizzare questo codice.
=> Visita qui per imparare C ++ da zero.
qual è il piano di test in qa
Cosa imparerai:
- Perché abbiamo bisogno dell'ereditarietà?
- Modalità di ereditarietà
- Ordine dei costruttori / distruttori in eredità
- Tipi di ereditarietà
- Ereditarietà del modello
- Composizione
- Come dovremmo decidere tra composizione ed eredità?
- Conclusione
- Lettura consigliata
Perché abbiamo bisogno dell'ereditarietà?
Considera un gruppo di veicoli come auto, autobus, jeep, ecc. Ciascuno di questi veicoli avrà proprietà e metodi come indicato nel diagramma sottostante.

Se ci viene richiesto di implementare singole classi per i veicoli di cui sopra, possiamo vedere che in tutte e tre le classi, dovremo scrivere lo stesso codice poiché tutti e tre i tipi di veicoli presentano più o meno le stesse proprietà. Ciò renderà il nostro programma inefficiente e macchinoso poiché ci sarà un sacco di codice duplicato.
Invece di scrivere un codice duplicato come sopra, possiamo implementare la funzionalità di ereditarietà per impedire la duplicazione del codice e anche scrivere un singolo pezzo di codice e usarlo in tutte e tre le classi. Questo è rappresentato pittoricamente come di seguito.

Nella figura sopra, abbiamo definito una classe di base 'Veicoli' e derivato le classi Auto, Autobus e Jeep da questa classe. I metodi e le proprietà comuni ora fanno parte della classe Veicoli. Poiché altre classi derivano dalla classe Vehicles, tutte le classi acquisiscono questi metodi e proprietà.
Quindi, dobbiamo solo scrivere il codice comune solo una volta e tutte e tre le classi; Auto, Bus e Jeep lo acquisteranno.
Quindi il vantaggio principale che otteniamo ereditando le classi esistenti o progettando un meccanismo di ereditarietà è la riusabilità del codice.
Ulteriori letture = >> Tutorial sull'ereditarietà di Java
Il formato generale per ereditare una classe è:
class derived_classname: access_specifier base_classname { }; Qui ' nome_classe_ derivato 'È il nome della classe derivata,' access_specifier 'È la modalità di accesso, ovvero pubblica, protetta o privata in cui la classe derivata deve ereditare la classe di base e' nome_classe_ derivato 'È il nome della classe base da cui eredita la classe derivata.
Modalità di ereditarietà
'Access_specifier' mostrato nella dichiarazione di ereditarietà sopra, può avere i loro valori come mostrato di seguito.

A seconda dell'access_specifier specificato quando ereditiamo la classe, abbiamo varie modalità di ereditarietà come elencato di seguito.
Eredità pubblica
Sintassi generale
class sub_class : public parent_class Quando si specifica l'identificatore di accesso pubblico, i membri pubblici della classe base vengono ereditati come pubblici mentre i membri protetti sono protetti. I membri privati rimangono privati. Questa è la modalità di eredità più popolare.
Eredità privata
Sintassi generale
class sub_class : parent_class L'eredità privata non eredita nulla. Quando viene utilizzato lo specificatore di accesso privato, anche i membri pubblici e protetti della classe base diventano privati.
Eredità protetta
Sintassi generale
class sub_class:protected parent_class Quando viene utilizzato l'identificatore di accesso protetto, i membri pubblici e protetti della classe base diventano membri protetti nella classe derivata.
Si noti che quando si utilizza lo specificatore di accesso privato per la classe di base, nessuno dei membri della classe di base viene ereditato. Diventano tutti privati nella classe derivata.
Di seguito viene fornita la rappresentazione tabellare di tutte le modalità di accesso e la loro interpretazione per l'ereditarietà.
| Classe derivata -> Classe base | Privato | Pubblico | Protetto |
|---|---|---|---|
| Privato | Non ereditato | Non ereditato | Non ereditato |
| Pubblico | Privato | Pubblico | Protetto |
| Protetto | Privato | Protetto | Protetto |
Ordine dei costruttori / distruttori in eredità
Quando le classi vengono ereditate, i costruttori vengono chiamati nello stesso ordine in cui vengono ereditate le classi. Se abbiamo una classe base e una classe derivata che eredita questa classe base, il costruttore della classe base (predefinito o parametrizzato) verrà chiamato per primo seguito dal costruttore della classe derivata.
Il seguente programma mostra l'ordine dei costruttori nell'ereditarietà. Abbiamo una classe Base 'Base' che ha un costruttore predefinito e un costruttore parametrizzato. Da questo deriviamo una classe chiamata “Derived” che ha anche un costruttore predefinito e un altro costruttore parametrizzato.
L'output di questo programma mostra l'ordine in cui vengono chiamati i costruttori.
#include using namespace std; //order of execution of constructors in inheritance class Base { int x; public: // default constructor Base() { cout Produzione:
Costruttore predefinito della classe base
Costruttore predefinito della classe base
Costruttore predefinito della classe derivata
Costruttore parametrizzato della classe base
Costruttore parametrizzato della classe derivata
Vediamo che dopo aver creato l'oggetto della classe base creiamo un oggetto della classe derivata con un costruttore predefinito. Quando viene creato questo oggetto, viene prima chiamato il costruttore predefinito della classe base e quindi viene eseguito il costruttore della classe derivata.
Allo stesso modo, quando l'oggetto della classe derivata viene creato utilizzando il costruttore parametrizzato, viene chiamato prima il costruttore parametrizzato della classe base e poi viene chiamato il costruttore della classe derivata.
Si noti che se non ci fosse un costruttore parametrizzato nella classe base, il costruttore predefinito sarebbe stato chiamato anche per costruire l'oggetto classe derivata parametrizzato.
Ma resta la domanda sul perché il costruttore della classe base viene chiamato durante la costruzione degli oggetti della classe derivata?
Sappiamo che un costruttore viene utilizzato per creare oggetti della classe e anche per inizializzare i membri della classe. Quando viene creato l'oggetto della classe derivata, il suo costruttore ha solo il controllo sui membri della classe derivata.
Tuttavia, la classe derivata eredita anche i membri della classe base. Se è stato chiamato solo il costruttore della classe derivata, i membri della classe base ereditati dalla classe derivata non verrebbero inizializzati correttamente.
qa tester intervista domande e risposte pdf
Di conseguenza, l'intero oggetto non verrà creato in modo efficiente. Questo è il motivo per cui tutti i costruttori della classe base vengono chiamati per primi quando viene creato un oggetto della classe derivata.
Tipi di ereditarietà
A seconda del modo in cui viene derivata la classe o del numero di classi base ereditate da una classe, abbiamo i seguenti tipi di ereditarietà come illustrato nella figura seguente.

Esploreremo ciascuno di questi tipi nel nostro prossimo tutorial sui 'Tipi di ereditarietà'.
Ereditarietà del modello
Quando la nostra implementazione coinvolge i modelli, allora dobbiamo ereditare o derivare dalle classi dei modelli e qui utilizziamo l'ereditarietà dei modelli.
Passiamo direttamente a un esempio di programmazione per comprendere meglio l'ereditarietà utilizzando i modelli.
#include using namespace std; //template inhertance templateclass basecls_Template { public: T value; basecls_Template(T value) { this->value = value; } void displayVal() { cout << value << endl; } }; //derived class inherits basecls_Template class derivedcls_Child : public basecls_Template { public: derivedcls_Child(/* no parameters */): basecls_Template( 0 ){ // default char is NULL; } derivedcls_Child(char c): basecls_Template( c ) { ; } void displayVal_drvd() { displayVal(); } }; int main() { basecls_Template obj( 100 ); derivedcls_Child obj1( 'A' ); cout<<'basecls_Template obj = '; obj.displayVal(); // should print '100' cout< Produzione:
basecls_Template obj = 100
Derivatocls_Child obj1 (ereditato da basecls_Template = A
Nel programma sopra, abbiamo un modello chiamato basecls_Template che definisce il modello di classe per la classe base. Successivamente, definiamo una classe derivatacls_Child che vogliamo derivare da una classe modello.
Ma si noti che la classe basecls_Template è solo un tipo e non una classe. Quindi, non possiamo derivare la classe derivatacls_Child da questo modello.
Quindi se dichiariamo la classe figlia come:
class derivedcls_Child : public basecls_Template Ciò comporterà un errore. Il motivo è basecls_Template è un tipo di dati e non una classe. Quindi, per ereditare i membri di basecls_Template, dovremmo prima istanziarlo prima di derivarne.
Pertanto la dichiarazione di cui sopra, Classe derivaticls_Child: public basecls_Template funziona bene.
In questa dichiarazione, abbiamo istanziato il modello basecls_Template in un modello di classe di caratteri. Una volta che usiamo questa classe modello istanziata, le altre cose che seguono come la creazione e l'utilizzo di oggetti coincidono con il normale funzionamento dell'ereditarietà.
Composizione
Finora abbiamo visto tutto sulle relazioni di eredità. L'ereditarietà rappresenta fondamentalmente il tipo di relazioni in cui la relazione indica una parte. Per esempio, un serpente è una specie di rettile. Possiamo anche dire che Reptile fa parte della classe Animal.
In conclusione, l'eredità indica 'È UN' tipo di relazioni in cui possiamo dire che la classe derivata è una parte della classe base.
Possiamo anche rappresentare le relazioni nel loro insieme. Per esempio, se diciamo che la classe Salary fa parte della classe Employee, non la rappresentiamo correttamente. Sappiamo che i dipendenti hanno uno stipendio. Quindi è più conveniente dire 'Il dipendente ha uno stipendio'.
Allo stesso modo, se prendiamo la classe Veicoli come esempio, possiamo dire che il veicolo ha il motore o il veicolo ha il telaio. Quindi tutte queste relazioni rappresentano 'HA UN' relazioni che rappresentano un intero oggetto contenuto in un'altra classe. Questo è definito come Composizione .
Le relazioni rappresentate dalla composizione dipendono l'una dall'altra. Per esempio, un telaio non può esistere senza un veicolo. Allo stesso modo, lo stipendio non può esistere senza un dipendente.
Possiamo rappresentare la composizione schematicamente come mostrato di seguito:

La composizione è anche chiamata contenimento. Nella rappresentazione sopra, abbiamo mostrato una classe genitore. A differenza dell'ereditarietà, includiamo un oggetto classe figlio all'interno della classe genitore. Questo è contenimento o composizione.
tecniche di test black box con esempi
Prendiamo un esempio di programmazione per capirlo.
#include using namespace std; //Composition example //Child class - address class Address { public: string houseNo, building, street, city, state; //Initialise the address object Address(string houseNo,string building,string street, string city, string state) { this->houseNo = houseNo; this->building = building; this->street = street; this->city = city; this->state = state; } }; //Parent class - Employee class Employee { private: Address* address; //composition->Employee has an address public: int empId; string empName; Employee(int empId, string empName, Address* address) { this->empId = empId; this->empName = empName; this->address = address; } void display() { cout< Produzione:
10001 Ved
A-101 Silver Springs Aundh Pune Maharashtra
In questo esempio, abbiamo una classe padre Employee e una classe figlia Address. All'interno della classe genitore Employee, abbiamo dichiarato un puntatore alla classe Address e inizializziamo anche questo oggetto nel costruttore Employee. Quindi descriviamo la relazione che il dipendente ha un indirizzo che è la composizione.
Come dovremmo decidere tra composizione ed eredità?
La composizione e l'ereditarietà descrivono entrambe le relazioni tra le classi. Mentre l'eredità descrive la relazione 'IS-A', la composizione raffigura la relazione 'HAS-A'.
Ora la domanda è: quando dovremmo usare l'ereditarietà e quando dovremmo usare la composizione? In realtà, non possiamo decidere le situazioni esatte in cui dovremmo usare nessuno dei due. Questo perché ognuno ha i suoi vantaggi e svantaggi.
Entrambi promuovono la riusabilità del codice. L'ereditarietà può rendere il codice ingombrante poiché le soluzioni diventano complesse ma, allo stesso tempo, ci consente anche di estendere il codice esistente. Pertanto, dovremmo usare l'ereditarietà quando il nostro requisito è modificare e utilizzare le proprietà e il metodo di un'altra classe all'interno della nuova classe.
In altre parole, quando vogliamo aggiungere più proprietà ed estendere la classe esistente. D'altra parte, quando non vogliamo modificare le proprietà e il comportamento di un'altra classe, ma semplicemente usarlo all'interno della classe, andiamo per la composizione.
Pertanto, la decisione migliore se utilizzare la composizione o l'eredità sarà presa valutando i pro ei contro di entrambe le tecniche per la situazione particolare.
= >> Leggi anche Composizione in Java
Conclusione
Quindi, siamo giunti alla fine del nostro argomento sull'eredità. Abbiamo visto varie modalità di eredità. Abbiamo anche visto i tipi di ereditarietà, che esploreremo nel nostro prossimo tutorial. Abbiamo appreso l'ordine dei costruttori eseguiti in caso di ereditarietà.
Abbiamo anche studiato i modelli e l'ereditarietà. È necessario creare un'istanza di un modello prima di poterlo utilizzare in eredità poiché il modello stesso è un tipo di dati e non possiamo ereditare da un tipo di dati.
La composizione è un altro tipo di relazione di classe e dobbiamo prima conoscere la situazione esatta e solo allora possiamo decidere se utilizzare la composizione o l'ereditarietà.
Nel nostro prossimo tutorial vedremo di più sui tipi di ereditarietà.
=> Guarda qui la serie di formazione C ++ semplice.
Lettura consigliata
- Tipi di ereditarietà in C ++
- Polimorfismo di runtime in C ++
- Funzioni Friend in C ++
- Uso del selenio Seleziona la classe per la gestione degli elementi a discesa su una pagina Web - Esercitazione sul selenio # 13
- Classi e oggetti in C ++
- Statico in C ++
- Tutorial su Unix Pipes: Pipes nella programmazione Unix
- Tutorial sull'interfaccia Java e sulla classe astratta con esempi

