Overerving in C++
Erfenis is een fundamenteel concept in de OOP (objectgeoriënteerd programmeren) . Het is het mechanisme waarmee een klasse de kenmerken (velden en methoden) van een andere klasse mag erven. Overerving betekent het creëren van nieuwe klassen op basis van bestaande klassen. Een klasse die overerft van een andere klasse kan de methoden en velden van die klasse hergebruiken.
Voorbeeld: In het volgende voorbeeld is Animal de basisklasse en zijn Dog Cat en Cow afgeleide klassen die de klasse Animal uitbreiden.
Inheritance C++ #include using namespace std ; class Animal { public : void sound () { cout < < 'Animal makes a sound' < < endl ; } }; class Dog : public Animal { public : void sound () { cout < < 'Dog barks' < < endl ; } }; class Cat : public Animal { public : void sound () { cout < < 'Cat meows' < < endl ; } }; class Cow : public Animal { public : void sound () { cout < < 'Cow moos' < < endl ; } }; int main () { Dog d ; d . sound (); Cat c ; c . sound (); Cow cow ; cow . sound (); return 0 ; }
Uitvoer
Dog barks Cat meows Cow moos
Uitleg:
- Animal is de basisklasse met een functie sound().
- Dog Cat en Cow zijn afgeleide klassen die elk hun eigen sound()-methode definiëren.
- In main() worden de objecten Hond Kat en Koe afzonderlijk gemaakt.
- Wanneer we sound() op elk object aanroepen, wordt de respectieve onderliggende klassemethode uitgevoerd (Hond blaft Kat miauwt Koe loeit).
Syntaxis
C++ class ChildClass : public ParentClass { // Additional fields and methods };
Hoe overerving werkt in C++?
De dubbele punt (:) met een toegangsspecificatie wordt gebruikt voor overerving in C++. Hiermee kan de afgeleide klasse (kindklasse) de gegevensleden (velden) en lidfuncties (methoden) van de basisklasse (ouderklasse) erven.
Wanneer een klasse een andere klasse erft, krijgt deze alle toegankelijke leden van de bovenliggende klasse en kan de onderliggende klasse deze ook opnieuw definiëren (overschrijven) of er nieuwe functionaliteit aan toevoegen.
Soorten overerving in C++
Hieronder staan de verschillende soorten overerving die door C++ worden ondersteund.
1. Enkelvoudige erfenis
Bij enkelvoudige overerving wordt een subklasse afgeleid van slechts één superklasse. Het erft de eigenschappen en het gedrag van een eenouderklasse. Soms wordt het ook wel eenvoudige overerving genoemd.
Single Inheritance C++ #include using namespace std ; class Vehicle { public : Vehicle () { cout < < 'This is a Vehicle' < < endl ; } }; class Car : public Vehicle { public : Car () { cout < < 'This Vehicle is Car' < < endl ; } }; int main () { Car obj ; return 0 ; }
Uitvoer
This is a Vehicle This Vehicle is Car
2. Meervoudige erfenis
In Meerdere erfenissen Eén klasse kan meer dan één superklasse hebben en kenmerken van alle bovenliggende klassen overnemen.
Multiple Inheritance C++ #include using namespace std ; class LandVehicle { public : void landInfo () { cout < < 'This is a LandVehicle' < < endl ; } }; class WaterVehicle { public : void waterInfo () { cout < < 'This is a WaterVehicle' < < endl ; } }; // Derived class inheriting from both base classes class AmphibiousVehicle : public LandVehicle public WaterVehicle { public : AmphibiousVehicle () { cout < < 'This is an AmphibiousVehicle' < < endl ; } }; int main () { AmphibiousVehicle obj ; obj . waterInfo (); obj . landInfo (); return 0 ; }
Uitvoer
This is an AmphibiousVehicle This is a WaterVehicle This is a LandVehicle
3. Overerving op meerdere niveaus
Overerving op meerdere niveaus in C++ betekent dat een klasse is afgeleid van een andere afgeleide klasse die een overervingsketen vormt.
Multilevel Inheritance C++ #include using namespace std ; class Vehicle { public : Vehicle () { cout < < 'This is a Vehicle' < < endl ; } }; // Derived class from Vehicle class FourWheeler : public Vehicle { public : FourWheeler () { cout < < '4 Wheeler Vehicles' < < endl ; } }; // Derived class from FourWheeler class Car : public FourWheeler { public : Car () { cout < < 'This 4 Wheeler Vehicle is a Car' < < endl ; } }; int main () { Car obj ; return 0 ; }
Uitvoer
This is a Vehicle 4 Wheeler Vehicles This 4 Wheeler Vehicle is a Car
4. Hiërarchische erfenis
Bij hiërarchische overerving wordt meer dan één subklasse geërfd van één enkele basisklasse. dat wil zeggen dat er meer dan één afgeleide klasse wordt gemaakt op basis van een enkele basisklasse. Auto's en bussen zijn bijvoorbeeld beide voertuigen.
Hierarchical Inheritance C++ #include using namespace std ; class Vehicle { public : Vehicle () { cout < < 'This is a Vehicle' < < endl ; } }; class Car : public Vehicle { public : Car () { cout < < 'This Vehicle is Car' < < endl ; } }; class Bus : public Vehicle { public : Bus () { cout < < 'This Vehicle is Bus' < < endl ; } }; int main () { Car obj1 ; Bus obj2 ; return 0 ; }
Uitvoer
This is a Vehicle This Vehicle is Car This is a Vehicle This Vehicle is Bus
5. Hybride erfenis
Wanneer twee of meer soorten overerving in één programma worden gecombineerd. Een klasse kan bijvoorbeeld meervoudige overerving gebruiken en ook deel uitmaken van een overervingsketen met meerdere niveaus.
Hybrid Inheritance C++ #include using namespace std ; class Vehicle { public : Vehicle () { cout < < 'This is a Vehicle' < < endl ; } }; class Fare { public : Fare () { cout < < 'Fare of Vehicle' < < endl ; } }; class Car : public Vehicle { public : Car () { cout < < 'This Vehical is a Car' < < endl ; } }; class Bus : public Vehicle public Fare { public : Bus () { cout < < 'This Vehicle is a Bus with Fare' ; } }; int main () { Bus obj2 ; return 0 ; }
Uitvoer
This is a Vehicle Fare of Vehicle This Vehicle is a Bus with Fare
Hybride overerving kan leiden tot de diamant probleem in C++. Dit gebeurt wanneer een klasse erft van twee klassen die beide dezelfde basisklasse delen. Als resultaat krijgt de afgeleide klasse meerdere kopieën van de leden van de basisklasse, wat onduidelijkheid creëert over welke te gebruiken.
Opmerking : De oplossing is om virtuele overerving te gebruiken, zodat slechts één kopie van de basisklasse wordt gedeeld.
Voordelen van overerving in C++
- Herbruikbaarheid van codes : Afgeleide klasse kan gegevensleden en methoden van de basisklasse direct hergebruiken, waardoor duplicatie van code wordt vermeden.
- Abstractie: Ondersteunt abstracte klassen (klassen met pure virtuele functies) die een gemeenschappelijke interface definiëren die abstractie afdwingt.
- Klassehiërarchie: U kunt hiërarchieën opbouwen (basis → afgeleid → verder afgeleid) om relaties uit de echte wereld te modelleren.
- Polymorfisme: Ondersteunt runtime-polymorfisme volledig via virtuele functies en ook compile-time polymorfisme via functie-overbelasting en sjablonen.
Nadelen van overerving in C++
- Strakke koppeling: De onderliggende klasse wordt afhankelijk van de ouderklasse. Elke verandering in de basisklasse kan veranderingen in afgeleide klassen afdwingen.
- Verminderde flexibiliteit: Soms wordt overerving misbruikt, waarbij samenstelling (heeft-een-relatie) beter zou kunnen leiden tot minder flexibele code.
- Verhoogde complexiteit: Diepe overervingshiërarchieën (meerdere niveaus of hybride) kunnen het moeilijk maken om de code te begrijpen, te onderhouden en te debuggen.
- Diamantprobleem: Bij hybride of meervoudige overerving kan er dubbelzinnigheid optreden als dezelfde basisklasse meerdere keren wordt overgeërfd.
- Overhead van virtuele functies: Als polymorfisme (virtuele functies) wordt gebruikt, is er een kleine runtime-overhead vanwege het opzoeken van virtuele tabellen.