inheritance c
Betydningen av arv i C ++ med eksempler:
Arv er en av de viktigste funksjonene i objektorientert programmering.
Arv er teknikken der en klasse tilegner seg egenskapene og metodene til en annen klasse. På denne måten kan vi gjenbruke koden som allerede er skrevet og verifisert. Klassen som tilegner seg egenskapene til en annen klasse kalles underklasse eller avledet klasse eller barneklasse.
Klassen hvis eiendommer erverves kalles basisklassen eller foreldreklassen eller superklassen. Når en klasse tilegner seg eller arver en annen klasse, så er alle egenskapene og metodene til basisklassen tilgjengelig for den avledede klassen, slik at vi kan bruke denne koden på nytt.
=> Besøk her for å lære C ++ fra grunnen.
de to viktigste elementene som ble testet i integrasjonstesten er grensesnittene og forventede resultater.
Hva du vil lære:
- Hvorfor trenger vi arv?
- Modus av arv
- Rekkefølge av konstruksjoner / ødelegger i arv
- Typer arv
- Malarv
- Sammensetning
- Hvordan skal vi bestemme mellom sammensetning og arv?
- Konklusjon
- Anbefalt lesing
Hvorfor trenger vi arv?
Vurder en gruppe biler som bil, buss, jeep osv. Hver av disse kjøretøyene vil ha egenskaper og metoder som angitt i diagrammet nedenfor.
Hvis vi er pålagt å implementere individuelle klasser for de ovennevnte kjøretøyene, kan vi se at i alle de tre klassene må vi skrive den samme koden som alle de tre kjøretøyene mer eller mindre har de samme egenskapene. Dette vil gjøre programmet vårt ineffektivt og tungvint, da det vil være mye duplikatkode.
I stedet for å skrive en duplisert kode som ovenfor, kan vi implementere funksjonen til arv for å forhindre at koden dupliseres, og også skrive en enkelt kode og bruke den i alle de tre klassene. Dette er illustrert som vist nedenfor.
I figuren ovenfor har vi definert en basisklasse 'Kjøretøy' og avledet klassene Bil, Buss og Jeep fra denne klassen. De vanlige metodene og egenskapene er en del av kjøretøyklassen nå. Ettersom andre klasser kommer fra kjøretøyklassen, tilegner alle klassene seg disse metodene og egenskapene.
Derfor trenger vi bare å skrive den vanlige koden bare én gang og alle tre klassene; Bil, buss og jeep vil anskaffe den.
Dermed får vi den største fordelen ved å arve eksisterende klasser eller designe arvsmekanisme, er gjenbrukbarhet av kode.
Videre lesing = >> Opplæring i Java-arv
Det generelle formatet for å arve en klasse er:
class derived_classname: access_specifier base_classname { };
Her “ derivated_classname ”Er navnet på den avledede klassen,“ tilgangsspesifikator 'Er tilgangsmodus dvs. offentlig, beskyttet eller privat der den avledede klassen må arve basisklassen og' derivated_classname ”Er navnet på basisklassen som den avledede klassen arver fra.
Modus av arv
'Access_specifier' vist i arverklæringen ovenfor kan ha verdiene som vist nedenfor.
Avhengig av tilgangsspesifikatoren som er angitt når vi arver klassen, har vi forskjellige arvemetoder som er oppført nedenfor.
Offentlig arv
Generell syntaks
class sub_class : public parent_class
Når spesifikk for offentlig tilgang er spesifisert, arves de offentlige medlemmene av baseklassen som offentlige mens beskyttede medlemmer er beskyttet. Private medlemmer forblir private. Dette er den mest populære arvemåten.
Privat arv
Generell syntaks
class sub_class : parent_class
Privat arv arver ikke noe. Når privat tilgangsspesifikator brukes, blir også offentlige og beskyttede medlemmer av baseklassen private.
Beskyttet arv
Generell syntaks
class sub_class:protected parent_class
Når spesifikator for beskyttet tilgang brukes, blir offentlige og beskyttede medlemmer av basisklassen beskyttede medlemmer i den avledede klassen.
Merk at når vi bruker privat tilgangsspesifikator for basisklassen, arves ingen av baseklassemedlemmene. De blir alle private i den avledede klassen.
Nedenfor er den tabellformede representasjonen av alle tilgangsmodusene og deres tolkning for arv.
Avledet klasse -> Grunnklasse | Privat | Offentlig | Beskyttet |
---|---|---|---|
Privat | Ikke arvet | Ikke arvet | Ikke arvet |
Offentlig | Privat | Offentlig | Beskyttet |
Beskyttet | Privat | Beskyttet | Beskyttet |
Rekkefølge av konstruksjoner / ødelegger i arv
Når klasser arves, kalles konstruktørene i samme rekkefølge som klassene arves. Hvis vi har en basisklasse og en avledet klasse som arver denne basisklassen, vil basisklassekonstruktøren (enten standard eller parameterisert) bli kalt først etterfulgt av den avledede klassekonstruktøren.
Følgende program demonstrerer rekkefølgen på konstruktører i arv. Vi har en baseklasse 'Base' som har en standard konstruktør og en parameterisert konstruktør. Vi henter en klasse fra dette kalt “Derived” som også har en standard og en annen parameterisert konstruktør.
Utgangen fra dette programmet viser rekkefølgen som konstruktørene kalles i.
#include using namespace std; //order of execution of constructors in inheritance class Base { int x; public: // default constructor Base() { cout Produksjon:
Basisklasse standard konstruktør
Basisklasse standard konstruktør
Avledet klasses standardkonstruktør
Baseklasseparameterisert konstruktør
Avledet klasseparameterisert konstruktør
Vi ser at etter å ha opprettet basisklasseobjektet, lager vi et avledet klasseobjekt med en standardkonstruktør. Når dette objektet er opprettet, blir først standardklassekonstruktøren kalt og deretter den avledede klassekonstruktøren utført.
Tilsvarende, når det avledede klasseobjektet blir opprettet ved hjelp av den parameteriserte konstruktøren, kalles den baserte klasseparameteriserte konstruktøren først, og deretter kalles den avledede klassekonstruktøren.
Merk at hvis det ikke var noen parametriserte konstruktører i baseklassen, ville standardkonstruktøren blitt kalt til og med for å konstruere det parameteriserte avledede klasseobjektet.
topp c ++ intervju spørsmål
Men spørsmålet gjenstår hvorfor baseklassekonstruktører kalles mens man konstruerer de avledede klasseobjektene?
Vi vet at en konstruktør brukes til å lage objekter i klassen og også til å initialisere medlemmene i klassen. Når det avledede klasseobjektet er opprettet, har konstruktøren bare kontroll over de avledede klassemedlemmene.
Den avledede klassen arver imidlertid også medlemmene av baseklassen. Hvis bare den avledede klassekonstruktøren ble kalt, ville ikke baseklassemedlemmene som ble arvet av den avledede klassen, initialisert riktig.
Som et resultat blir ikke hele objektet opprettet effektivt. Dette er grunnen til at alle basisklassekonstruktører blir kalt først når et avledet klasseobjekt opprettes.
Typer arv
Avhengig av måten klassen er avledet på eller hvor mange baseklasser en klasse arver, har vi følgende typer arv som vist i figuren nedenfor.

Vi vil utforske hver av disse typene i vår neste opplæring om 'Typer av arv'.
Malarv
Når implementeringen vår innebærer maler, må vi arve eller utlede fra malklasser, og vi bruker malarv der.
La oss hoppe direkte til et programmeringseksempel for å bedre forstå arven ved hjelp av maler.
#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< Produksjon:
basecls_Template obj = 100
derivatedcls_Child obj1 (arvet fra basecls_Template = A
I programmet ovenfor har vi en mal som heter basecls_Template som definerer klassemalen for basisklassen. Deretter definerer vi en klasse derivatedcls_Child som vi ønsker å utlede fra en malklasse.
Men merk at klassen basecls_Template bare er en type og ikke en klasse. Derfor kan vi ikke utlede klassen derivatedcls_Child fra denne malen.
Derfor hvis vi erklærer barneklassen som:
class derivedcls_Child : public basecls_Template
Dette vil føre til en feil. Årsaken til at basecls_Template er en datatype og ikke klasse. Derfor, for å arve medlemmene av basecls_Template, bør vi først instansiere det før vi kommer fra det.
Derfor ovenstående uttalelse, Class derivatedcls_Child: public basecls_Template fungerer fint.
I denne uttalelsen har vi instantiert malen basecls_Template til en tegnklassmal. Når vi har brukt denne instantierte malklassen, faller de andre tingene som følger, som å lage og bruke objekter sammen med den vanlige arvearbeidet.
Sammensetning
Så langt har vi sett alt om arveforhold. Arv skildrer i utgangspunktet den typen forhold der forholdet indikerer en del. For eksempel, en slange er en slags reptil. Vi kan også si at reptil er en del av dyreklassen.
Avslutningsvis indikerer arv 'ER EN' slags forhold der vi kan si at den avledede klassen er en del av basisklassen.
Vi kan også representere relasjoner som en helhet. For eksempel, Hvis vi sier at lønnsklasse er en del av arbeidstakerklassen, representerer vi den ikke ordentlig. Vi vet at ansatte har lønn. Dermed er det mer praktisk å si “Arbeidstaker har lønn”.
Tilsvarende, hvis vi tar kjøretøyklassen som et eksempel, kan vi si at kjøretøyet har motor eller kjøretøyet har chassis. Dermed skildrer alle disse forholdene 'HAR EN' relasjoner som representerer et helt objekt som inngår i en annen klasse. Dette er definert som Sammensetning .
Forhold avbildet av komposisjon er avhengige av hverandre. For eksempel, et chassis kan ikke eksistere uten et kjøretøy. Tilsvarende kan ikke lønn eksistere uten en ansatt.
Vi kan representere sammensetningen diagrammatisk som vist nedenfor:

Sammensetningen kalles også inneslutning. I representasjonen ovenfor har vi vist en foreldreklasse. I motsetning til arv inkluderer vi et barneklasseobjekt i foreldreklassen. Dette er inneslutning eller sammensetning.
c ++ tegn til int
La oss ta et programmeringseksempel for å forstå dette.
#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< Produksjon:
10001 Ved
A-101 Silver Springs Aundh Pune Maharashtra
I dette eksemplet har vi en foreldreklasse ansatt og en barneklasse-adresse. Inne i foreldreklassen Medarbeider har vi erklært en pekepinn til Adresseklassen og også initialisert dette objektet i Medarbeiderkonstruktøren. Dermed skildrer vi forholdet mellom at ansatt har en adresse som er sammensetning.
Hvordan skal vi bestemme mellom sammensetning og arv?
Komposisjon og arv skildrer begge forholdet mellom klassene. Mens arv skildrer “IS-A” forholdet, viser sammensetningen “HAS-A” forhold.
Nå er spørsmålet at når skal vi bruke arv og når skal vi bruke komposisjon? Egentlig kan vi ikke bestemme nøyaktige situasjoner som når vi skal bruke noen av dem. Dette er fordi hver har sine egne fordeler og ulemper.
Begge fremmer kode gjenbrukbarhet. Arv kan gjøre koden klumpete ettersom løsningene blir kompliserte, men samtidig lar det oss også utvide den eksisterende koden. Derfor bør vi bruke arv når vårt krav er å endre og bruke egenskapene og metoden til en annen klasse i den nye klassen.
Med andre ord når vi vil legge til flere egenskaper og utvide den eksisterende klassen. På den annen side, når vi ikke vil endre egenskapene og oppførselen til en annen klasse, men bare bruke den inne i klassen, går vi for komposisjon.
Dermed er den beste avgjørelsen om du vil bruke komposisjon eller arv ved å veie fordeler og ulemper ved begge teknikkene for den spesielle situasjonen.
= >> Les også Komposisjon i Java
Konklusjon
Dermed har vi kommet til slutten av vårt emne om arv. Vi har sett ulike former for arv. Vi har også sett hvilke typer arv, som vi vil utforske i vår neste opplæring. Vi lærte om rekkefølgen på konstruktører som utføres i tilfelle arv.
Vi studerte også om maler og arv. Vi må instansiere en mal før vi kan bruke den i arv, da selve malen er en datatype, og vi kan ikke arve fra en datatype.
Komposisjonen er en annen type klasseforhold, og vi trenger å vite den nøyaktige situasjonen først, og bare vi kan bestemme om vi vil bruke komposisjon eller arv.
I vår kommende opplæring vil vi se mer om arvetyper.
=> Se opp den enkle C ++ treningsserien her.
Anbefalt lesing
- Typer arv i C ++
- Runtime Polymorphism In C ++
- Vennfunksjoner i C ++
- Bruk av selen valgt klasse for håndtering av nedtrekkselementer på en webside - Selenium-veiledning nr. 13
- Klasser og objekter i C ++
- Statisk i C ++
- Unix Pipes Tutorial: Pipes in Unix Programming
- Java-grensesnitt og abstrakt klasseopplæring med eksempler