Het vermogen van een klas eigenschappen en karakteristieken uit een andere klasse afleiden heet Erfenis . Overerving is een van de belangrijkste kenmerken van objectgeoriënteerd programmeren.
Overerving is een functie of een proces waarbij nieuwe klassen worden gemaakt op basis van de bestaande klassen. De nieuw gemaakte klasse wordt afgeleide klasse of onderliggende klasse genoemd en de bestaande klasse staat bekend als de basisklasse of bovenliggende klasse. Er wordt nu gezegd dat de afgeleide klasse wordt geërfd van de basisklasse.
Als we zeggen dat de afgeleide klasse de basisklasse erft, betekent dit dat de afgeleide klasse alle eigenschappen van de basisklasse erft, zonder de eigenschappen van de basisklasse te veranderen en nieuwe functies aan zijn eigen eigenschappen kan toevoegen. Deze nieuwe functies in de afgeleide klasse hebben geen invloed op de basisklasse. De afgeleide klasse is de gespecialiseerde klasse voor de basisklasse.
- Subklasse: De klasse die eigenschappen van een andere klasse erft, wordt Subklasse of Afgeleide klasse genoemd.
- Superklasse: De klasse waarvan de eigenschappen worden overgenomen door een subklasse, wordt Basisklasse of Superklasse genoemd.
Het artikel is onderverdeeld in de volgende subonderwerpen:
- Waarom en wanneer overerving gebruiken?
- Wijze van overerving
- Soorten erfenis
Waarom en wanneer overerving gebruiken?
Beschouw een groep voertuigen. Je moet klassen maken voor Bus, Auto en Vrachtwagen. De methoden brandstofAmount(), capaciteit(), applyBrakes() zullen voor alle drie de klassen hetzelfde zijn. Als we deze klassen maken om overerving te vermijden, moeten we al deze functies in elk van de drie klassen schrijven, zoals weergegeven in de onderstaande afbeelding:

Actrice Rakul Preet Singh
Je kunt duidelijk zien dat het bovenstaande proces resulteert in het driemaal dupliceren van dezelfde code. Dit vergroot de kans op fouten en gegevensredundantie. Om dit soort situaties te voorkomen, wordt er gebruik gemaakt van overerving. Als we een klasse Voertuig creëren en deze drie functies daarin schrijven en de rest van de klassen van de voertuigklasse erven, kunnen we eenvoudigweg de duplicatie van gegevens vermijden en de herbruikbaarheid vergroten. Kijk naar het onderstaande diagram waarin de drie klassen worden overgenomen van de voertuigklasse:

Met behulp van overerving hoeven we de functies slechts één keer te schrijven in plaats van drie keer, omdat we de rest van de drie klassen hebben geërfd van de basisklasse (Vehicle).
Overerving implementeren in C++ : Voor het maken van een subklasse die wordt geërfd van de basisklasse, moeten we de onderstaande syntaxis volgen.
Afgeleide klassen: Een afgeleide klasse wordt gedefinieerd als de klasse die is afgeleid van de basisklasse.
Syntaxis :
class : { //body }>Waar
class — trefwoord om een nieuwe klasse te maken
afgeleide_klasse_naam — naam van de nieuwe klasse, die de basisklasse zal erven
toegangsspecificatie — privé, openbaar of beschermd. Als geen van beide is opgegeven, wordt PRIVATE als standaard gebruikt
basisklassenaam — naam van de basisklasse
Opmerking : Een afgeleide klasse erft niet toegang aan leden met privégegevens. Het erft echter wel een volledig bovenliggend object, dat alle privéleden bevat die door die klasse worden gedeclareerd.
Voorbeeld:
1. klasse ABC: privé XYZ //privé afleiding
{ }
2. klasse ABC: openbare XYZ //openbare afleiding
{ }
3. klasse ABC: beschermde XYZ //beschermde afleiding
{ }
4. klasse ABC: XYZ // standaard privé-afleiding
{ }
Opmerking:
o Wanneer een basisklasse privé wordt geërfd door de afgeleide klasse, worden publieke leden van de basisklasse de private leden van de afgeleide klasse en daarom zijn de publieke leden van de basisklasse alleen toegankelijk voor de lidfuncties van de afgeleide klasse. Ze zijn niet toegankelijk voor de objecten van de afgeleide klasse.
o Aan de andere kant, wanneer de basisklasse publiekelijk wordt geërfd door de afgeleide klasse, worden publieke leden van de basisklasse ook de publieke leden van de afgeleide klasse. Daarom zijn de publieke leden van de basisklasse toegankelijk voor de objecten van de afgeleide klasse, maar ook voor de lidfuncties van de afgeleide klasse.
// Example: define member function without argument within // the class #include using namespace std; class Person { int id; char name[100]; public: void set_p() { cout << 'Enter the Id:'; cin>> identiteitskaart; uit<< 'Enter the Name:'; cin>> naam; } void display_p() { cout<< endl <<'Id: '<< id << '
Name: ' << name <> cursus; uit<< 'Enter the Course Fee:'; cin>> vergoeding; } void display_s() {display_p(); uit<<'Course: '<< course << '
Fee: ' << fee << endl; } }; int main() { Student s; s.set_s(); s.display_s(); return 0; }> Uitgang:
c booleaans
Enter the Id: 101 Enter the Name: Dev Enter the Course Name: GCS Enter the Course Fee:70000 Id: 101 Name: Dev Course: GCS Fee: 70000>C++
// Example: define member function without argument outside the class #include using namespace std; class Person { int id; char name[100]; public: void set_p(); void display_p(); }; void Person::set_p() { cout<<'Enter the Id:'; cin>>id; uit<<'Enter the Name:'; cin>>naam; } void Persoon::display_p() { cout<>cursus; uit<<'Enter the Course Fee:'; cin>> vergoeding; } void Student::display_s() { display_p(); uit<<'
Course: '< Uitgang:
Enter the Id: 101 Enter the Name: Dev Enter the Course Name: GCS Enter the Course Fee: 70000 Id: 101 Name: Dev Course: GCS Fee: 70000>C++
// Example: define member function with argument outside the class #include #include using namespace std; class Person { int id; char name[100]; public: void set_p(int,char[]); void display_p(); }; void Person::set_p(int id,char n[]) { this->ID=ID; strcpy(deze->naam,n); } void Persoon::display_p() { cout< CPP
// C++ program to demonstrate implementation // of Inheritance #include using namespace std; // Base class class Parent { public: int id_p; }; // Sub class inheriting from Base Class(Parent) class Child : public Parent { public: int id_c; }; // main function int main() { Child obj1; // An object of class child has all data members // and member functions of class parent obj1.id_c = 7; obj1.id_p = 91; cout << 'Child id is: ' << obj1.id_c << '
'; cout << 'Parent id is: ' << obj1.id_p << '
'; return 0; }> Uitvoer
Child id is: 7 Parent id is: 91>
In het bovenstaande programma wordt de klasse ‘Child’ publiekelijk geërfd van de klasse ‘Parent’, dus de openbare gegevensleden van de klasse ‘Parent’ zullen ook worden overgenomen door de klasse ‘Child’.
Wijze van overerving: Er zijn 3 manieren van overerving.
- Openbare modus : Als we een subklasse afleiden van een openbare basisklasse. Vervolgens wordt het openbare lid van de basisklasse openbaar in de afgeleide klasse en worden beschermde leden van de basisklasse beschermd in de afgeleide klasse.
- Beveiligde modus : Als we een subklasse afleiden van een beschermde basisklasse. Dan worden zowel publieke leden als beschermde leden van de basisklasse beschermd in de afgeleide klasse.
- Prive modus : Als we een subklasse afleiden van een Private-basisklasse. Dan worden zowel publieke leden als beschermde leden van de basisklasse privé in de afgeleide klasse.
Opmerking: De privéleden in de basisklasse zijn niet rechtstreeks toegankelijk in de afgeleide klasse, terwijl beschermde leden rechtstreeks toegankelijk zijn. De klassen B, C en D bevatten bijvoorbeeld allemaal de variabelen x, y en z in het onderstaande voorbeeld. Het is slechts een kwestie van toegang.
CPP // C++ Implementation to show that a derived class // doesn’t inherit access to private data members. // However, it does inherit a full parent object. class A { public: int x; protected: int y; private: int z; }; class B : public A { // x is public // y is protected // z is not accessible from B }; class C : protected A { // x is protected // y is protected // z is not accessible from C }; class D : private A // 'private' is default for classes { // x is private // y is private // z is not accessible from D };>
De onderstaande tabel vat de bovenstaande drie modi samen en toont de toegangsspecificatie van de leden van de basisklasse in de subklasse wanneer afgeleid in de openbare, beschermde en privé-modi:

Soorten erfenis: -
- Enkelvoudige erfenis
- Overerving op meerdere niveaus
- Meerdere erfenissen
- Hiërarchische erfenis
- Hybride overerving
Soorten overerving in C++
1. Enkelvoudige erfenis : Bij enkelvoudige overerving mag een klasse slechts van één klasse erven. dat wil zeggen dat één subklasse slechts door één basisklasse wordt geërfd.

Syntaxis :
class subclass_name : access_mode base_class { // body of subclass }; OR class A { ... .. ... }; class B: public A { ... .. ... };>CPP // C++ program to explain // Single inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // sub class derived from a single base classes class Car : public Vehicle { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes Car obj; return 0; }> Uitvoer
This is a Vehicle>
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A() { cout<<'Enter the Value of A='; cin>> een; } void disp_A() { cout< Uitvoer:- Voer de waarde in van A= 3 3 Voer de waarde in van B= 5 5 Product van 3 * 5 = 15
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A(int x) { a=x; } void disp_A() { cout< Uitvoer
Product of 4 * 5 = 20>
2. Meervoudige erfenis: Meervoudige overerving is een functie van C++ waarbij een klasse van meer dan één klasse kan erven. d.w.z. één subklasse wordt geërfd van meer dan één basisklasse .

Syntaxis :
class subclass_name : access_mode base_class1, access_mode base_class2, .... { // body of subclass }; class B { ... .. ... }; class C { ... .. ... }; class A: public B, public C { ... ... ... };>Hier wordt het aantal basisklassen gescheiden door een komma (‘, ‘) en moet de toegangsmodus voor elke basisklasse worden gespecificeerd.
CPP // C++ program to explain // multiple inheritance #include using namespace std; // first base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // second base class class FourWheeler { public: FourWheeler() { cout << 'This is a 4 wheeler Vehicle
'; } }; // sub class derived from two base classes class Car : public Vehicle, public FourWheeler { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes. Car obj; return 0; }> Uitvoer
This is a Vehicle This is a 4 wheeler Vehicle>
C++
// Example: #include using namespace std; class A { protected: int a; public: void set_A() { cout<<'Enter the Value of A='; cin>> een; } void disp_A() { cout<
Wilt u er meer over weten, raadpleeg dan het artikel Meerdere erfenissen .
3. Overerving op meerdere niveaus : Bij dit type overerving wordt een afgeleide klasse gemaakt op basis van een andere afgeleide klasse.

polymorfisme in Java
Syntaxis:-
class C { ... .. ... }; class B:public C { ... .. ... }; class A: public B { ... ... ... };>CPP // C++ program to implement // Multilevel Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // first sub_class derived from class vehicle class fourWheeler : public Vehicle { public: fourWheeler() { cout << 'Objects with 4 wheels are vehicles
'; } }; // sub class derived from the derived base class fourWheeler class Car : public fourWheeler { public: Car() { cout << 'Car has 4 Wheels
'; } }; // main function int main() { // Creating object of sub class will // invoke the constructor of base classes. Car obj; return 0; }> Uitvoer
This is a Vehicle Objects with 4 wheels are vehicles Car has 4 Wheels>
4. Hiërarchische erfenis : Bij dit type 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.

Syntaxis:-
class A { // body of the class A. } class B : public A { // body of class B. } class C : public A { // body of class C. } class D : public A { // body of class D. }>CPP // C++ program to implement // Hierarchical Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // first sub class class Car : public Vehicle { }; // second sub class class Bus : public Vehicle { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base class. Car obj1; Bus obj2; return 0; }> Uitvoer
This is a Vehicle This is a Vehicle>
5. Hybride (virtuele) erfenis : Hybride overerving wordt geïmplementeerd door meer dan één type overerving te combineren. Bijvoorbeeld: het combineren van hiërarchische overerving en meervoudige overerving.
Onderstaande afbeelding toont de combinatie van hiërarchische en meervoudige overerving:

// C++ program for Hybrid Inheritance #include using namespace std; // base class class Vehicle { public: Vehicle() { cout << 'This is a Vehicle
'; } }; // base class class Fare { public: Fare() { cout << 'Fare of Vehicle
'; } }; // first sub class class Car : public Vehicle { }; // second sub class class Bus : public Vehicle, public Fare { }; // main function int main() { // Creating object of sub class will // invoke the constructor of base class. Bus obj2; return 0; }> Uitvoer
This is a Vehicle Fare of Vehicle>C++
// Example: #include using namespace std; class A { protected: int a; public: void get_a() { cout << 'Enter the value of 'a' : '; cin>> een; } }; klasse B: openbaar A { beschermd: int b; public: void get_b() { cout<< 'Enter the value of 'b' : '; cin>>b; } }; klasse C { beschermd: int c; public: void get_c() {cout<< 'Enter the value of c is : '; cin>>c; } }; klasse D: publiek B, publiek C { beschermd: int d; openbaar: void mul() {get_a(); get_b(); get_c(); uit<< 'Multiplication of a,b,c is : ' <
6. Een speciaal geval van hybride overerving: Multipath-overerving :
Een afgeleide klasse met twee basisklassen en deze twee basisklassen hebben één gemeenschappelijke basisklasse, wordt multipath-overerving genoemd. Bij dit soort erfenissen kan er onduidelijkheid ontstaan.
Voorbeeld:
// C++ program demonstrating ambiguity in Multipath // Inheritance #include using namespace std; class ClassA { public: int a; }; class ClassB : public ClassA { public: int b; }; class ClassC : public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; int main() { ClassD obj; // obj.a = 10; // Statement 1, Error // obj.a = 100; // Statement 2, Error obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << ' a from ClassB : ' << obj.ClassB::a; cout << '
a from ClassC : ' << obj.ClassC::a; cout << '
b : ' << obj.b; cout << '
c : ' << obj.c; cout << '
d : ' << obj.d << '
'; }> Uitvoer
a from ClassB : 10 a from ClassC : 100 b : 20 c : 30 d : 40>
In het bovenstaande voorbeeld erven zowel Klasse B als Klasse C Klasse A, ze hebben allebei één exemplaar van Klasse A. Klasse-D erft echter zowel KlasseB als KlasseC, daarom heeft Klasse-D twee exemplaren van KlasseA, één van KlasseB en een andere van KlasseC.
Als we toegang moeten krijgen tot het gegevenslid van Klasse A via het object van Klasse D, moeten we het pad specificeren van waaruit toegang wordt verkregen tot a, of het nu van Klasse B of Klasse C is. De bcoz-compiler kan geen onderscheid maken tussen twee exemplaren van Klasse A in Klasse-D.
Er zijn twee manieren om deze dubbelzinnigheid te vermijden:
1) Dubbelzinnigheid vermijden met behulp van de scope-resolutie-operator: Met behulp van de scope-resolutieoperator kunnen we handmatig het pad specificeren van waaruit toegang wordt verkregen tot gegevenslid a, zoals weergegeven in de instructies 3 en 4 in het bovenstaande voorbeeld.
CPP obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4>
Opmerking: Toch zijn er twee exemplaren van Klasse A in Klasse D.
2) Dubbelzinnigheid vermijden met behulp van de virtuele basisklasse:
c structuur in structuurCPP
#include class ClassA { public: int a; }; class ClassB : virtual public ClassA { public: int b; }; class ClassC : virtual public ClassA { public: int c; }; class ClassD : public ClassB, public ClassC { public: int d; }; int main() { ClassD obj; obj.a = 10; // Statement 3 obj.a = 100; // Statement 4 obj.b = 20; obj.c = 30; obj.d = 40; cout << '
a : ' << obj.a; cout << '
b : ' << obj.b; cout << '
c : ' << obj.c; cout << '
d : ' << obj.d << '
'; }> Uitgang:
a : 100 b : 20 c : 30 d : 40>
Volgens het bovenstaande voorbeeld heeft Klasse-D slechts één kopie van KlasseA, daarom overschrijft instructie 4 de waarde van a, gegeven in instructie 3.