inheritance c
Betydelsen av arv i C ++ med exempel:
Arv är en av de viktigaste funktionerna i objektorienterad programmering.
Arv är den teknik genom vilken en klass förvärvar egenskaperna och metoderna för en annan klass. På så sätt kan vi återanvända koden som redan är skriven och verifierad. Klassen som förvärvar egenskaperna för en annan klass kallas underklass eller härledd klass eller underklass.
Den klass vars egenskaper förvärvas kallas basklassen eller föräldraklassen eller superklassen. När en klass förvärvar eller ärver en annan klass, är alla basklassens egenskaper och metoder tillgängliga för den härledda klassen, så att vi kan återanvända den här koden.
=> Besök här för att lära dig C ++ från Scratch.
hur man öppnar en .apk fil
Vad du kommer att lära dig:
- Varför behöver vi arv?
- Lägen för arv
- Order av konstruktörer / förstörare i arv
- Typer av arv
- Mallarv
- Sammansättning
- Hur ska vi välja mellan sammansättning och arv?
- Slutsats
- Rekommenderad läsning
Varför behöver vi arv?
Tänk på en grupp fordon som bil, buss, jeep, etc. Var och en av dessa fordon har egenskaper och metoder som anges i nedanstående diagram.
Om vi är skyldiga att implementera enskilda klasser för ovanstående fordon kan vi se att i alla de tre klasserna måste vi skriva samma kod som alla tre typerna av fordon mer eller mindre uppvisar samma egenskaper. Detta kommer att göra vårt program ineffektivt och besvärligt eftersom det kommer att finnas mycket duplikatkod.
Istället för att skriva en duplicerad kod som ovan kan vi implementera funktionen av arv för att förhindra att koden dupliceras och även skriva en enda kod och använda den i alla de tre klasserna. Detta visas i bild enligt nedan.
I figuren ovan har vi definierat en basklass 'Fordon' och härledt klasserna bil, buss och jeep från denna klass. De vanliga metoderna och egenskaperna ingår nu i fordonsklassen. Eftersom andra klasser kommer från fordonsklassen, förvärvar alla klasser dessa metoder och egenskaper.
Därför behöver vi bara skriva den gemensamma koden bara en gång och alla tre klasserna; Bil, buss och jeep kommer att förvärva det.
Således får vi den största fördelen genom att ärva befintliga klasser eller utforma arvsmekanism är återanvändbarhet av kod.
Ytterligare läsning = >> Java Inheritance Tutorial
Det allmänna formatet för att ärva en klass är:
class derived_classname: access_specifier base_classname { };
Här “ härledd_klassnamn ”Är namnet på den härledda klassen,” access_specifier 'Är åtkomstläget dvs offentligt, skyddat eller privat där den härledda klassen måste ärva basklassen och' härledd_klassnamn ”Är namnet på basklassen från vilken den härledda klassen ärver.
Lägen för arv
'Access_specifier' som visas i ovanstående arvsdeklaration kan ha sina värden enligt nedan.
Beroende på vilken access_specifier som anges när vi ärver klassen har vi olika arvsätt som anges nedan.
Offentlig arv
Allmän syntax
class sub_class : public parent_class
När allmän åtkomstspecifikator anges, ärvs de offentliga medlemmarna i basklassen som offentliga medan skyddade medlemmar skyddas. Privata medlemmar förblir privata. Detta är det mest populära arvsättet.
Privat arv
Allmän syntax
class sub_class : parent_class
Privat arv ärver inte något. När specifik åtkomstspecifikator används, blir även offentliga och skyddade medlemmar i basklassen privata.
Skyddad arv
Allmän syntax
class sub_class:protected parent_class
När specifik åtkomstspecifikator används, blir offentliga och skyddade medlemmar i basklassen skyddade medlemmar i den härledda klassen.
Observera att när vi använder specifik åtkomstspecifikator för basklassen ärvs ingen av basklassmedlemmarna. De blir alla privata i den härledda klassen.
Nedan visas den tabellformade representationen av alla åtkomstlägen och deras tolkning för arv.
Avledad klass -> Basklass | Privat | offentlig | Skyddade |
---|---|---|---|
Privat | Inte ärvt | Inte ärvt | Inte ärvt |
offentlig | Privat | offentlig | Skyddade |
Skyddade | Privat | Skyddade | Skyddade |
Order av konstruktörer / förstörare i arv
När klasser ärvs kallas konstruktörerna i samma ordning som klasserna ärvs. Om vi har en basklass och en härledd klass som ärver den här basklassen kommer basklasskonstruktören (antingen standard eller parametrerad) att anropas först följt av den härledda klasskonstruktören.
Följande program visar ordningen på konstruktörer i arv. Vi har en basklass 'bas' som har en standardkonstruktör och en parametrerad konstruktör. Vi härleder en klass från detta som kallas 'härledd' som också har en standard och en annan parametrerad konstruktor.
Utgången från detta program visar i vilken ordning konstruktörerna anropas.
#include using namespace std; //order of execution of constructors in inheritance class Base { int x; public: // default constructor Base() { cout Produktion:
Baskonstruktör för basklass
Baskonstruktör för basklass
Deriverad klasskonstruktör för klass
Basklass parametrerad konstruktör
Deriverad klassparameteriserad konstruktör
Vi ser att efter att ha skapat basklassobjektet skapar vi ett härledt klassobjekt med en standardkonstruktör. När detta objekt skapas anropas först basklassens standardkonstruktör och sedan körs den härledda klasskonstruktören.
På samma sätt, när det härledda klassobjektet skapas med hjälp av den parametrerade konstruktorn, kallas basklassens parametrerade konstruktör först och sedan anropas den härledda klasskonstruktören.
Observera att om det inte fanns någon parametrerad konstruktör i basklassen, skulle standardkonstruktören ha anropats även för att konstruera det parametrerade härledda klassobjektet.
Men frågan kvarstår varför basklasskonstruktör anropas medan man konstruerar de härledda klassobjekten?
Vi vet att en konstruktör används för att skapa objekt i klassen och även för att initialisera medlemmarna i klassen. När det härledda klassobjektet skapas har dess konstruktör bara kontroll över de härledda klassmedlemmarna.
Den härledda klassen ärver dock också medlemmarna i basklassen. Om bara den härledda klasskonstruktören anropades, skulle basklassmedlemmarna som ärvts av den härledda klassen inte initialiseras ordentligt.
Som ett resultat skapas inte hela objektet effektivt. Detta är anledningen till att alla basklasskonstruktörer anropas först när ett härledt klassobjekt skapas.
Typer av arv
Beroende på hur klassen härleds eller hur många basklasser en klass ärver har vi följande typer av arv som avbildas i figuren nedan.
selen hitta element med css väljare
Vi kommer att utforska var och en av dessa typer i vår nästa handledning om 'Typer av arv'.
Mallarv
När vår implementering innefattar mallar, måste vi ärva eller härleda från mallklasser, och vi använder mallarv där.
Låt oss direkt hoppa till ett programmeringsexempel för att bättre förstå arvet med hjälp av mallar.
#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< Produktion:
basecls_Template obj = 100
derivatedcls_Child obj1 (ärvt från basecls_Template = A
I ovanstående program har vi en mall med namnet basecls_Template som definierar klassmallen för basklassen. Därefter definierar vi en klass derivatedcls_Child som vi vill härleda från en mallklass.
Men notera att klassen basecls_Template bara är en typ och inte en klass. Därför kan vi inte härleda klassen derivatedcls_Child från den här mallen.
Om vi därför förklarar barnklassen som:
class derivedcls_Child : public basecls_Template
Detta kommer att resultera i ett fel. Anledningen till att basecls_Template är en datatyp och inte klass. För att ärva medlemmarna i basecls_Template bör vi alltså först instansiera det innan vi härleder från det.
Därför ovanstående uttalande, Class derivatedcls_Child: public basecls_Template Fungerar bra.
I detta uttalande har vi instantierat mallen basecls_Template till en teckenklassmall. När vi väl har använt denna instanserade mallklass sammanfaller de andra sakerna som följer som att skapa och använda objekt med det vanliga arv som fungerar.
Sammansättning
Hittills har vi sett allt om arvsförhållanden. Arv skildrar i grunden vilken typ av relationer där förhållandet indikerar en del. Till exempel, en orm är ett slags reptil. Vi kan också säga att Reptil är en del av djurklassen.
Sammanfattningsvis indikerar arv 'ÄR EN' typ av relationer där vi kan säga att den härledda klassen är en del av basklassen.
Vi kan också representera relationer som helhet. Till exempel, om vi säger att löneklassen är en del av arbetstagarklassen, representerar vi inte den ordentligt. Vi vet att anställda har lön. Det är alltså bekvämare att säga ”Anställd har lön”.
På samma sätt, om vi tar fordonsklassen som ett exempel, kan vi säga att fordonet har motor eller fordonet har chassi. Således skildrar alla dessa relationer 'HAR EN' relationer som representerar ett helt objekt som ingår i en annan klass. Detta definieras som Sammansättning .
Relationer som avbildas av komposition är beroende av varandra. Till exempel, ett chassi kan inte existera utan ett fordon. På samma sätt kan lön inte existera utan en anställd.
Vi kan representera kompositionen schematiskt enligt nedan:
Kompositionen kallas också Containment. I ovanstående representation har vi visat en överordnad klass. Till skillnad från arv inkluderar vi ett barnklassobjekt i föräldraklassen. Detta är inneslutning eller komposition.
gratis mp3 nedladdningsapp för android
Låt oss ta ett programmeringsexempel för att förstå detta.
#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< Produktion:
10001 Ved
A-101 Silver Springs Aundh Pune Maharashtra
I det här exemplet har vi en föräldraklass Anställd och en barnklassadress. Inuti föräldraklassen Anställd har vi förklarat en pekare till adressklassen och initierat också detta objekt i anställdkonstruktören. Således visar vi förhållandet att anställd har en adress som är sammansättning.
Hur ska vi välja mellan sammansättning och arv?
Sammansättning och arv visar båda förhållandena mellan klasserna. Medan arv skildrar 'IS-A' -förhållandet, visar kompositionen 'HAS-A' -förhållande.
Nu är frågan att när ska vi använda arv och när ska vi använda komposition? Egentligen kan vi inte bestämma exakta situationer som när vi ska använda någon av dem. Detta beror på att var och en har sina egna fördelar och nackdelar.
Båda främjar återanvändbarhet. Arv kan göra koden skrymmande eftersom lösningarna blir komplexa men samtidigt tillåter det oss också att utöka den befintliga koden. Därför bör vi använda arv när vårt krav är att ändra och använda egenskaperna och metoden för en annan klass i den nya klassen.
Med andra ord, när vi vill lägga till fler egenskaper och utöka den befintliga klassen. Å andra sidan, när vi inte vill ändra egenskaperna och beteendet hos en annan klass, utan bara använda den i klassen, går vi för komposition.
Således är det bästa beslutet att använda komposition eller arv genom att väga för- och nackdelar med båda teknikerna för den specifika situationen.
= >> Läs även Komposition i Java
Slutsats
Således har vi kommit till slutet av vårt ämne om arv. Vi har sett olika arvsmetoder. Vi har också sett vilka typer av arv som vi kommer att utforska i vår nästa handledning. Vi lärde oss om ordningen på konstruktörer som utförs vid arv.
Vi studerade också om mallar och arv. Vi måste starta en mall innan vi kan använda den i arv eftersom själva mallen är en datatyp och vi inte kan ärva från en datatyp.
Kompositionen är en annan typ av klassförhållande och vi måste först veta den exakta situationen och då kan vi bara bestämma om vi vill använda komposition eller arv.
I vår kommande handledning kommer vi att se mer om typerna av arv.
=> Se upp den enkla C ++ träningsserien här.
Rekommenderad läsning
- Typer av arv i C ++
- Runtime Polymorphism In C ++
- Vänfunktioner i C ++
- Användning av Selen Select Class för hantering av rullgardinselement på en webbsida - Selen Tutorial # 13
- Klasser och objekt i C ++
- Statisk i C ++
- Unix Pipes Tutorial: Pipes in Unix Programming
- Java-gränssnitt och abstrakt klasshandledning med exempel