Galimybė a klasė išvesti savybes ir charakteristikas iš kitos klasės vadinama Paveldėjimas . Paveldėjimas yra viena iš svarbiausių objektinio programavimo savybių.
Paveldėjimas yra funkcija arba procesas, kurio metu iš esamų klasių sukuriamos naujos klasės. Sukurta nauja klasė vadinama išvestine klase arba antrine klase, o esama klasė vadinama bazine arba pirmine klase. Teigiama, kad išvestinė klasė dabar yra paveldėta iš bazinės klasės.
Kai sakome, kad išvestinė klasė paveldi bazinę klasę, tai reiškia, kad išvestinė klasė paveldi visas bazinės klasės savybes, nekeičiant pagrindinės klasės savybių ir gali pridėti naujų savybių. Šios naujos išvestinės klasės funkcijos neturės įtakos bazinei klasei. Išvestinė klasė yra specializuota bazinės klasės klasė.
- Subklasė: Klasė, kuri paveldi savybes iš kitos klasės, vadinama poklasiu arba išvestine klase.
- Super klasė: Klasė, kurios savybes paveldi poklasis, vadinama bazine klase arba superklase.
Straipsnis suskirstytas į šias potemes:
- Kodėl ir kada naudoti paveldėjimą?
- Paveldėjimo būdai
- Paveldėjimo rūšys
Kodėl ir kada naudoti paveldėjimą?
Apsvarstykite transporto priemonių grupę. Turite sukurti autobusų, automobilių ir sunkvežimių klases. Metodai fuelAmount(), capaces(), applyBrakes() bus vienodi visoms trims klasėms. Jei sukursime šias klases vengdami paveldėjimo, turime parašyti visas šias funkcijas kiekvienoje iš trijų klasių, kaip parodyta paveikslėlyje žemiau:

kas yra ypatingas veikėjas
Galite aiškiai matyti, kad aukščiau aprašytas procesas lemia to paties kodo dubliavimą 3 kartus. Tai padidina klaidų ir duomenų pertekliaus tikimybę. Siekiant išvengti tokios situacijos, naudojamas paveldėjimas. Jei sukursime klasę Transporto priemonė ir joje įrašysime šias tris funkcijas, o likusias klases paveldėsime iš transporto priemonių klasės, tuomet paprasčiausiai išvengsime duomenų dubliavimo ir padidinsime pakartotinį naudojimą. Pažiūrėkite į toliau pateiktą diagramą, kurioje trys klasės yra paveldimos iš transporto priemonių klasės:

Naudodami paveldėjimą, funkcijas turime parašyti tik vieną kartą, o ne tris kartus, nes likusias tris klases paveldėjome iš pagrindinės klasės (Transporto priemonė).
Paveldėjimo įgyvendinimas C++ : Norėdami sukurti poklasį, kuris yra paveldėtas iš pagrindinės klasės, turime vadovautis toliau pateikta sintaksė.
Išvestinės klasės: Išvestinė klasė apibrėžiama kaip klasė, gauta iš bazinės klasės.
Sintaksė :
class : { //body }>Kur
klasė – raktinis žodis, norint sukurti naują klasę
derived_class_name – naujos klasės, kuri paveldės bazinę klasę, pavadinimas
prieigos specifikatorius – privatus, viešas arba apsaugotas. Jei nė vienas nenurodytas, PRIVATUS laikomas kaip numatytasis
base-class-name — pagrindinės klasės pavadinimas
Pastaba : išvestinė klasė nepaveldi prieiga privačių duomenų nariams. Tačiau ji paveldi visą pirminį objektą, kuriame yra visi privatūs nariai, kuriuos ta klasė deklaruoja.
Pavyzdys:
1. klasė ABC : privatus XYZ //privatus darinys
{ }
2. klasė ABC : viešas XYZ //viešas darinys
{ }
3. klasė ABC : apsaugotas XYZ //apsaugotas darinys
{ }
4. ABC klasė: XYZ //privatus darinys pagal nutylėjimą
{ }
Pastaba:
o Kai bazinę klasę privačiai paveldi išvestinė klasė, viešieji bazinės klasės nariai tampa privačiais išvestinės klasės nariais, todėl bazinės klasės viešuosius narius gali pasiekti tik išvestinės klasės narių funkcijos. Jie yra nepasiekiami išvestinės klasės objektams.
o Kita vertus, kai bazinę klasę viešai paveldi išvestinė klasė, viešieji bazinės klasės nariai tampa ir išvestinės klasės viešaisiais nariais. Todėl bazinės klasės viešieji nariai yra prieinami tiek išvestinės klasės objektams, tiek išvestinės klasės narių funkcijoms.
// 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>> id; cout<< 'Enter the Name:'; cin>> vardas; } void display_p() { cout<< endl <<'Id: '<< id << '
Name: ' << name <> kursas; cout<< 'Enter the Course Fee:'; cin>> mokestis; } void display_s() { display_p(); cout<<'Course: '<< course << '
Fee: ' << fee << endl; } }; int main() { Student s; s.set_s(); s.display_s(); return 0; }> Išvestis:
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; cout<<'Enter the Name:'; cin>> vardas; } void Asmuo::display_p() { cout<>kursas; cout<<'Enter the Course Fee:'; cin>>mokestis; } void Studentas::display_s() { display_p(); cout<<'
Course: '< Išvestis:
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(šis->vardas,n); } void Asmuo::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; }> Išvestis
Child id is: 7 Parent id is: 91>
Pirmiau nurodytoje programoje klasė „Vaikas“ yra viešai paveldėta iš „Tėvų“ klasės, todėl klasės „Tėvai“ viešuosius duomenis paveldės klasė „Vaikas“.
Paveldėjimo būdai: Yra 3 paveldėjimo būdai.
- Viešasis režimas : Jei išvesime poklasį iš viešosios bazinės klasės. Tada viešasis bazinės klasės narys taps viešas išvestinėje klasėje, o saugomi bazinės klasės nariai taps apsaugoti išvestinėje klasėje.
- Apsaugotas režimas : Jei poklasį išvesime iš apsaugotos bazinės klasės. Tada ir viešieji nariai, ir apsaugoti bazinės klasės nariai bus apsaugoti išvestinėje klasėje.
- Privatus režimas : Jei poklasį išvesime iš privačios bazinės klasės. Tada ir viešieji nariai, ir apsaugoti bazinės klasės nariai išvestinėje klasėje taps privačiais.
Pastaba: Privatūs bazinės klasės nariai negali būti tiesiogiai pasiekti išvestinėje klasėje, o apsaugoti nariai gali būti tiesiogiai pasiekti. Pavyzdžiui, toliau pateiktame pavyzdyje B, C ir D klasėse yra kintamieji x, y ir z. Tai tik prieigos klausimas.
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 };>
Žemiau esančioje lentelėje apibendrinami trys pirmiau minėti režimai ir rodomas poklasio bazinės klasės narių prieigos specifikatorius, kai jis gaunamas viešuoju, apsaugotu ir privačiu režimais:

klausytis uosto
Paveldėjimo tipai: -
- Vienkartinis paveldėjimas
- Daugiapakopis paveldėjimas
- Daugialypis paveldėjimas
- Hierarchinis paveldėjimas
- Hibridinis paveldėjimas
Paveldėjimo tipai C++
1. Vienkartinis paveldėjimas : Vienkartinio paveldėjimo atveju klasei leidžiama paveldėti tik iš vienos klasės. y., vieną poklasį paveldi tik viena bazinė klasė.

Sintaksė :
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; }> Išvestis
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>>a; } void disp_A() { cout< Išvestis: - Įveskite A reikšmę = 3 3 Įveskite B reikšmę = 5 5 Produktas iš 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< Išvestis
Product of 4 * 5 = 20>
2. Daugkartinis paveldėjimas: Kelias paveldėjimas yra C++ funkcija, kai klasė gali paveldėti iš daugiau nei vienos klasės. t.y vienas poklasis yra paveldima iš daugiau nei vieno bazinė klasė .

Sintaksė :
class subclass_name : access_mode base_class1, access_mode base_class2, .... { // body of subclass }; class B { ... .. ... }; class C { ... .. ... }; class A: public B, public C { ... ... ... };>Čia bazinių klasių skaičius bus atskirtas kableliu (', ') ir turi būti nurodytas kiekvienos bazinės klasės prieigos režimas.
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; }> Išvestis
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>>a; } void disp_A() { cout<
Norėdami sužinoti daugiau apie tai, skaitykite straipsnį Keli paveldėjimai .
3. Daugiapakopis paveldėjimas : Šio tipo paveldėjimo atveju išvestinė klasė sukuriama iš kitos išvestinės klasės.

gimė Freddie Mercury
Sintaksė: -
mylivericket
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; }> Išvestis
This is a Vehicle Objects with 4 wheels are vehicles Car has 4 Wheels>
4. Hierarchinis paveldėjimas : Šio tipo paveldėjimo atveju daugiau nei vienas poklasis yra paveldimas iš vienos bazinės klasės. y., iš vienos bazinės klasės sukuriama daugiau nei viena išvestinė klasė.

Sintaksė: -
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; }> Išvestis
This is a Vehicle This is a Vehicle>
5. Hibridinis (virtualus) paveldėjimas : Hibridinis paveldėjimas įgyvendinamas derinant daugiau nei vieną paveldėjimo tipą. Pavyzdžiui: Hierarchinio paveldėjimo ir kelių paveldėjimo derinimas.
Žemiau esančiame paveikslėlyje parodytas hierarchinio ir daugialypio paveldėjimo derinys:

// 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; }> Išvestis
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>>a; } }; B klasė: viešoji A {saugoma: int b; vieša: void get_b() { cout<< 'Enter the value of 'b' : '; cin>>b; } }; klasė C {saugoma: int c; public: void get_c() { cout<< 'Enter the value of c is : '; cin>>c; } }; D klasė: viešoji B, viešoji C {saugoma: int d; public: void mul() { get_a(); gauti_b(); get_c(); cout<< 'Multiplication of a,b,c is : ' <
6. Ypatingas hibridinio paveldėjimo atvejis: Daugiatakis paveldėjimas :
Išvestinė klasė, turinti dvi bazines klases ir šios dvi pagrindinės klasės turi vieną bendrą bazinę klasę, vadinama kelių takų paveldėjimu. Šio tipo paveldėjimo atveju gali kilti neaiškumų.
Pavyzdys:
// 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 << '
'; }> Išvestis
a from ClassB : 10 a from ClassC : 100 b : 20 c : 30 d : 40>
Aukščiau pateiktame pavyzdyje ir ClassB, ir ClassC paveldi A klasę, jos abi turi vieną A klasės kopiją. Tačiau D klasė paveldi ir B, ir C klasę, todėl D klasė turi dvi A klasės kopijas – vieną iš B klasės, kitą – iš C klasės.
Jei mums reikia pasiekti A klasės duomenų narį per D klasės objektą, turime nurodyti kelią, iš kurio bus pasiekiama a, nesvarbu, ar jis yra iš B klasės, ar iš C klasės, bcoz kompiliatorius negali atskirti dviejų A klasės kopijų. D klasė.
Yra 2 būdai, kaip išvengti šios dviprasmybės:
1) Dviprasmybių išvengimas naudojant apimties skyros operatorių: Naudodami apimties skyros operatorių galime rankiniu būdu nurodyti kelią, iš kurio bus pasiekiamas duomenų narys a, kaip parodyta aukščiau pateiktame pavyzdyje 3 ir 4 sakiniuose.
CPP obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4>
Pastaba: Vis dėlto D klasėje yra dvi A klasės kopijos.
2) Dviprasmybių išvengimas naudojant virtualią bazinę klasę:
#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 << '
'; }> Išvestis:
a : 100 b : 20 c : 30 d : 40>
Remiantis aukščiau pateiktu pavyzdžiu, D klasė turi tik vieną A klasės kopiją, todėl 4 teiginys perrašys a reikšmę, pateiktą 3 sakinyje.