logo

Dedičnosť v C++

Schopnosť a trieda odvodiť vlastnosti a charakteristiky z inej triedy je tzv Dedičnosť . Dedičnosť je jednou z najdôležitejších vlastností objektovo orientovaného programovania.

Dedičnosť je vlastnosť alebo proces, v ktorom sa z existujúcich tried vytvárajú nové triedy. Nová vytvorená trieda sa nazýva odvodená trieda alebo podradená trieda a existujúca trieda je známa ako základná trieda alebo rodičovská trieda. Teraz sa hovorí, že odvodená trieda je zdedená zo základnej triedy.



Keď povieme, že odvodená trieda zdedí základnú triedu, znamená to, že odvodená trieda zdedí všetky vlastnosti základnej triedy bez toho, aby zmenila vlastnosti základnej triedy a môže pridať nové funkcie k svojim vlastným. Tieto nové funkcie v odvodenej triede neovplyvnia základnú triedu. Odvodená trieda je špecializovanou triedou pre základnú triedu.

  • Podtrieda: Trieda, ktorá dedí vlastnosti z inej triedy, sa nazýva podtrieda alebo odvodená trieda.
  • Super trieda: Trieda, ktorej vlastnosti sú dedené podtriedou, sa nazýva Base Class alebo Superclass.

Článok je rozdelený do nasledujúcich podtém:

  • Prečo a kedy použiť dedičnosť?
  • Spôsoby dedičnosti
  • Typy dedičstva

Prečo a kedy použiť dedičnosť?

Zvážte skupinu vozidiel. Musíte vytvoriť triedy pre autobusy, autá a nákladné autá. Metódy fuelAmount(), capacity(), applyBrakes() budú rovnaké pre všetky tri triedy. Ak vytvoríme tieto triedy, aby sme sa vyhli dedičnosti, potom musíme všetky tieto funkcie napísať do každej z troch tried, ako je znázornené na obrázku nižšie:



dedičnosť v C++

operačný systém linux

Môžete jasne vidieť, že vyššie uvedený proces vedie k duplikácii toho istého kódu 3 krát. To zvyšuje pravdepodobnosť chyby a redundancie údajov. Aby sa predišlo tomuto typu situácie, používa sa dedičnosť. Ak vytvoríme triedu Vehicle a napíšeme do nej tieto tri funkcie a zdedíme zvyšok tried z triedy vozidla, potom sa môžeme jednoducho vyhnúť duplicite údajov a zvýšiť opätovnú použiteľnosť. Pozrite sa na nižšie uvedený diagram, v ktorom sú tri triedy zdedené z triedy vozidla:

aplikácia dedičnosti v C++



Pomocou dedičnosti musíme funkcie napísať iba raz namiesto trikrát, pretože sme zdedili zvyšok troch tried zo základnej triedy (Vehicle).
Implementácia dedičnosti v C++ : Na vytvorenie podtriedy, ktorá je zdedená zo základnej triedy, musíme postupovať podľa nižšie uvedenej syntaxe.

Odvodené triedy: Odvodená trieda je definovaná ako trieda odvodená od základnej triedy.
Syntax :

class :  {  //body }>

Kde
class — kľúčové slovo na vytvorenie novej triedy
derivovaný_názov_triedy — názov novej triedy, ktorá zdedí základnú triedu
špecifikátor prístupu – súkromný, verejný alebo chránený. Ak nie je zadané ani jedno, ako predvolené sa použije PRIVATE
base-class-name — názov základnej triedy
Poznámka : Odvodená trieda nededí prístup na členov so súkromnými údajmi. Dedí však úplný nadradený objekt, ktorý obsahuje všetkých súkromných členov, ktorých táto trieda deklaruje.

Príklad:
1. trieda ABC : súkromné ​​XYZ //súkromné ​​odvodenie
{ }
2. trieda ABC : verejné XYZ //verejné odvodenie
{ }
3. trieda ABC : chránená XYZ //chránená derivácia
{ }
4. trieda ABC: XYZ //štandardne súkromné ​​odvodenie
{ }

Poznámka:

o Keď je základná trieda súkromne zdedená odvodenou triedou, verejní členovia základnej triedy sa stanú súkromnými členmi odvodenej triedy, a preto k verejným členom základnej triedy môžu pristupovať iba členské funkcie odvodenej triedy. Sú neprístupné pre objekty odvodenej triedy.
o Na druhej strane, keď je základná trieda verejne zdedená odvodenou triedou, verejní členovia základnej triedy sa tiež stávajú verejnými členmi odvodenej triedy. Verejní členovia základnej triedy sú preto prístupní pre objekty odvodenej triedy, ako aj pre členské funkcie odvodenej triedy.

C++
// 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>> meno;  } void display_p() { cout<< endl <<'Id: '<< id << '
Name: ' << name <> samozrejme;  cout<< 'Enter the Course Fee:';  cin>> poplatok;  } void display_s() { display_p();  cout<<'Course: '<< course << '
Fee: ' << fee << endl;  } }; int main() {  Student s;  s.set_s();  s.display_s();  return 0; }>

Výkon:

dereferenčný ukazovateľ
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>>meno; } void Osoba::display_p() { cout<>samozrejme;  cout<<'Enter the Course Fee:';  cin>>poplatok; } void Študent::display_s() { display_p();  cout<<'
Course: '<

Výkon:

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(toto->meno,n);  } void Osoba::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; }>

Výkon
Child id is: 7 Parent id is: 91>

Vo vyššie uvedenom programe je trieda „Dieťa“ verejne zdedená z triedy „Rodič“, takže členovia triedy „Parent“ s verejnými údajmi budú tiež zdedení triedou „Dieťa“.
Spôsoby dedičnosti: Existujú 3 spôsoby dedenia.

  1. Verejný režim : Ak odvodíme podtriedu z verejnej základnej triedy. Potom sa verejný člen základnej triedy stane verejným v odvodenej triede a chránení členovia základnej triedy sa stanú chránenými v odvodenej triede.
  2. Chránený režim : Ak odvodíme podtriedu z chránenej základnej triedy. Potom sa verejní členovia aj chránení členovia základnej triedy stanú chránenými v odvodenej triede.
  3. Súkromný režim : Ak odvodíme podtriedu zo súkromnej základnej triedy. Potom sa verejní členovia aj chránení členovia základnej triedy stanú súkromnými v odvodenej triede.

Poznámka: K súkromným členom v základnej triede nie je možné priamo pristupovať v odvodenej triede, zatiaľ čo k chráneným členom možno pristupovať priamo. Napríklad všetky triedy B, C a D obsahujú premenné x, y a z v nižšie uvedenom príklade. Je to len otázka prístupu.

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 };>


Nižšie uvedená tabuľka sumarizuje vyššie uvedené tri režimy a zobrazuje špecifikátor prístupu členov základnej triedy v podtriede, keď sú odvodené vo verejnom, chránenom a súkromnom režime:

Typy dedičstva: -

  1. Jediné dedičstvo
  2. Viacúrovňová dedičnosť
  3. Viacnásobné dedičstvo
  4. Hierarchické dedičstvo
  5. Hybridné dedičstvo

Typy dedičnosti v C++

1. Jediné dedičstvo : Pri jednoduchom dedení môže trieda dediť iba z jednej triedy. t.j. jednu podtriedu zdedí iba jedna základná trieda.

Jednoduché dedičstvo v C++

Syntax :

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; }>

Výkon
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<Výstup:- Zadajte hodnotu A= 3 3 Zadajte hodnotu B= 5 5 Súčin 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<Product of 4 * 5 = 20>

2. Viacnásobné dedičstvo: Viacnásobná dedičnosť je vlastnosťou C++, kde trieda môže dediť z viac ako jednej triedy. t.j. jeden podtrieda sa dedí z viac ako jedného základná trieda .

Viacnásobné dedičstvo v C++

Syntax :

class subclass_name : access_mode base_class1, access_mode base_class2, .... {  // body of subclass }; class B {  ... .. ...  }; class C { ... .. ... }; class A: public B, public C { ... ... ... };>

Tu bude počet základných tried oddelený čiarkou (‘, ‘) a musí byť špecifikovaný režim prístupu pre každú základnú triedu.

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; }>

Výkon
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<Ak sa o tom chcete dozvedieť viac, pozrite si článok Viacnásobné dedičstvo .


3. Viacúrovňová dedičnosť : Pri tomto type dedenia sa odvodená trieda vytvorí z inej odvodenej triedy.

Viacúrovňová dedičnosť v C++

jeden milión v číslach

Syntax:-

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; }>

Výkon
This is a Vehicle Objects with 4 wheels are vehicles Car has 4 Wheels>

4. Hierarchická dedičnosť : Pri tomto type dedenia sa z jednej základnej triedy dedí viac ako jedna podtrieda. t.j. z jednej základnej triedy sa vytvorí viac ako jedna odvodená trieda.

Hierarchická dedičnosť v C++

Syntax:-

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; }>

Výkon
This is a Vehicle This is a Vehicle>

5. Hybridné (virtuálne) dedičstvo : Hybridné dedičstvo sa implementuje kombináciou viac ako jedného typu dedičstva. Napríklad: Kombinácia hierarchickej dedičnosti a viacnásobnej dedičnosti.
Obrázok nižšie ukazuje kombináciu hierarchického a viacnásobného dedičstva:

Hybridná dedičnosť v C++.

CPP
// 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; }>

Výkon
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;   } };    trieda B : public A { protected: int b;   public: void get_b() { cout<< 'Enter the value of 'b' : ';  cin>>b;   } };  trieda C { chránená: int c;   public: void get_c() { cout<< 'Enter the value of c is : ';   cin>>c;   } };    trieda D : public B, public C { protected: int d;   public: void mul() { get_a();   get_b();   get_c();   cout<< 'Multiplication of a,b,c is : ' < 

6. Špeciálny prípad hybridnej dedičnosti: Viaccestná dedičnosť :
Odvodená trieda s dvoma základnými triedami a tieto dve základné triedy majú jednu spoločnú základnú triedu sa nazýva viaccestná dedičnosť. Pri tomto type dedenia môže vzniknúť nejednoznačnosť.
Príklad:

CPP
// 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 << '
'; }>

Výkon
 a from ClassB : 10 a from ClassC : 100 b : 20 c : 30 d : 40>

Vo vyššie uvedenom príklade trieda B aj trieda C zdedia triedu A, obe majú jednu kópiu triedy A. Trieda-D však dedí triedu B aj triedu C, preto má trieda D dve kópie triedy A, jednu z triedy B a druhú z triedy C.
Ak potrebujeme pristupovať k dátovému členu triedy A cez objekt triedy D, musíme zadať cestu, z ktorej sa bude pristupovať k a, či už z triedy B alebo triedy C, kompilátor bcoz nedokáže rozlíšiť medzi dvoma kópiami triedy A v Trieda-D.

Existujú 2 spôsoby, ako sa vyhnúť tejto nejednoznačnosti:

1) Vyhnite sa nejednoznačnosti pomocou operátora rozlíšenia rozsahu: Pomocou operátora rozlíšenia rozsahu môžeme manuálne určiť cestu, z ktorej sa bude pristupovať k údajovému členu a, ako je znázornené vo výrokoch 3 a 4 vo vyššie uvedenom príklade.

CPP
obj.ClassB::a = 10; // Statement 3 obj.ClassC::a = 100; // Statement 4>


Poznámka: Napriek tomu existujú dve kópie triedy A v triede D.
2) Vyhnite sa nejednoznačnosti pomocou virtuálnej základnej triedy:

mylivecricket
CPP
#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 << '
'; }>

Výkon:

a : 100 b : 20 c : 30 d : 40>

Podľa vyššie uvedeného príkladu má trieda-D iba jednu kópiu triedy A, preto príkaz 4 prepíše hodnotu a uvedenú v príkaze 3.