logo

Moștenirea în C++

Capacitatea de a clasă a deriva proprietăți și caracteristici dintr-o altă clasă se numește Moştenire . Moștenirea este una dintre cele mai importante caracteristici ale programării orientate pe obiecte.

Moștenirea este o caracteristică sau un proces în care sunt create noi clase din clasele existente. Noua clasă creată se numește clasă derivată sau clasă copil, iar clasa existentă este cunoscută ca clasă de bază sau clasă părinte. Clasa derivată acum se spune că este moștenită din clasa de bază.



Când spunem că clasa derivată moștenește clasa de bază, înseamnă că clasa derivată moștenește toate proprietățile clasei de bază, fără a modifica proprietățile clasei de bază și poate adăuga noi caracteristici proprii. Aceste caracteristici noi din clasa derivată nu vor afecta clasa de bază. Clasa derivată este clasa specializată pentru clasa de bază.

  • Subclasa: Clasa care moștenește proprietăți de la o altă clasă se numește Subclass sau Derived Class.
  • Super clasă: Clasa ale cărei proprietăți sunt moștenite de o subclasă se numește Clasă de bază sau Superclasă.

Articolul este împărțit în următoarele subteme:

  • De ce și când să folosiți moștenirea?
  • Moduri de moștenire
  • Tipuri de moștenire

De ce și când să folosiți moștenirea?

Luați în considerare un grup de vehicule. Trebuie să creați clase pentru autobuz, mașină și camion. Metodele fuelAmount(), capacity(), applyBrakes() vor fi aceleași pentru toate cele trei clase. Dacă creăm aceste clase evitând moștenirea, atunci trebuie să scriem toate aceste funcții în fiecare dintre cele trei clase, așa cum se arată în figura de mai jos:



moștenirea în C++

np.clip

Puteți vedea clar că procesul de mai sus duce la duplicarea aceluiași cod de 3 ori. Acest lucru crește șansele de eroare și redundanță a datelor. Pentru a evita acest tip de situație, se folosește moștenirea. Dacă creăm o clasă Vehicule și scriem aceste trei funcții în ea și moștenim restul claselor din clasa vehiculului, atunci putem pur și simplu să evităm duplicarea datelor și să creștem reutilizabilitatea. Priviți diagrama de mai jos în care cele trei clase sunt moștenite de la clasa vehiculului:

aplicație de moștenire în C++



Folosind moștenirea, trebuie să scriem funcțiile o singură dată în loc de trei ori, deoarece am moștenit restul celor trei clase din clasa de bază (Vehicul).
Implementarea moștenirii în C++ : Pentru a crea o sub-clasă care este moștenită din clasa de bază, trebuie să urmărim sintaxa de mai jos.

Clase derivate: O clasă derivată este definită ca o clasă derivată din clasa de bază.
Sintaxă :

class :  {  //body }>

Unde
class — cuvânt cheie pentru a crea o nouă clasă
derived_class_name — numele noii clase, care va moșteni clasa de bază
access-specificer — fie privat, public sau protejat. Dacă niciunul nu este specificat, PRIVAT este considerat implicit
nume-clasă de bază — numele clasei de bază
Notă : O clasă derivată nu moștenește acces pentru membrii datelor private. Cu toate acestea, moștenește un obiect părinte complet, care conține orice membru privat pe care acea clasă îi declară.

Exemplu:
1. clasa ABC : private XYZ //private derivation
{ }
2. clasa ABC : public XYZ //public derivation
{ }
3. clasa ABC : protected XYZ //protected derivation
{ }
4. clasa ABC: XYZ //derivare privată implicit
{ }

Notă:

o Când o clasă de bază este moștenită în mod privat de clasa derivată, membrii publici ai clasei de bază devin membrii privați ai clasei derivate și, prin urmare, membrii publici ai clasei de bază pot fi accesați numai de funcțiile membre ale clasei derivate. Sunt inaccesibile obiectelor clasei derivate.
o Pe de altă parte, atunci când clasa de bază este moștenită public de clasa derivată, membrii publici ai clasei de bază devin și membri publici ai clasei derivate. Prin urmare, membrii publici ai clasei de bază sunt accesibile de către obiectele clasei derivate precum și de funcțiile membre ale clasei derivate.

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

Ieșire:

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>>nume; } void Person::display_p() { cout<> curs;  cout<<'Enter the Course Fee:';  cin>> taxa; } void Student::display_s() { display_p();  cout<<'
Course: '<

Ieșire:

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(acest->nume,n);  } void Person::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; }>

Ieșire
Child id is: 7 Parent id is: 91>

În programul de mai sus, clasa „Copil” este moștenită public de la clasa „Părinte”, astfel încât membrii datelor publice ai clasei „Părinte” vor fi, de asemenea, moșteniți de clasa „Copil”.
Modalitati de mostenire: Există 3 moduri de moștenire.

coada de prioritate java
  1. Modul public : Dacă derivăm o subclasă dintr-o clasă de bază publică. Apoi, membrul public al clasei de bază va deveni public în clasa derivată, iar membrii protejați ai clasei de bază vor deveni protejați în clasa derivată.
  2. Mod protejat : Dacă derivăm o subclasă dintr-o clasă de bază protejată. Apoi, atât membrii publici, cât și membrii protejați ai clasei de bază vor deveni protejați în clasa derivată.
  3. Modul privat : Dacă derivăm o subclasă dintr-o clasă de bază Private. Apoi, atât membrii publici, cât și membrii protejați ai clasei de bază vor deveni Private în clasa derivată.

Notă: Membrii privați din clasa de bază nu pot fi accesați direct în clasa derivată, în timp ce membrii protejați pot fi accesați direct. De exemplu, clasele B, C și D conțin toate variabilele x, y și z din exemplul de mai jos. Este doar o chestiune de acces.

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


Tabelul de mai jos rezumă cele trei moduri de mai sus și arată specificatorul de acces al membrilor clasei de bază din subclasă atunci când sunt derivate în modurile public, protejat și privat:

Tipuri de moștenire: -

  1. Moștenire unică
  2. Moștenirea pe mai multe niveluri
  3. Moștenire multiplă
  4. Moștenirea ierarhică
  5. Moștenirea hibridă

Tipuri de moștenire în C++

1. Moștenire unică : În moștenirea unică, o clasă are voie să moștenească dintr-o singură clasă. adică o subclasă este moștenită de o singură clasă de bază.

Moștenire unică în C++

Sintaxă :

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

Ieșire
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<Ieșire: - Introduceți valoarea lui A= 3 3 Introduceți valoarea lui B= 5 5 Produsul lui 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. Moștenire multiplă: Moștenirea multiplă este o caracteristică a C++ în care o clasă poate moșteni de la mai multe clase. adică unul subclasă este moștenit de la mai mult de unul clasa de bază .

Moștenire multiplă în C++

Sintaxă :

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

Aici, numărul de clase de bază va fi separat prin virgulă (‘, ‘) și trebuie specificat modul de acces pentru fiecare clasă de bază.

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

Ieșire
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<Pentru a afla mai multe despre el, vă rugăm să consultați articolul Moșteniri multiple .


3. Moștenirea pe mai multe niveluri : În acest tip de moștenire, o clasă derivată este creată dintr-o altă clasă derivată.

Moștenire pe mai multe niveluri în C++

bash for loop

Sintaxă:-

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

Ieșire
This is a Vehicle Objects with 4 wheels are vehicles Car has 4 Wheels>

4. Moștenirea ierarhică : În acest tip de moștenire, mai multe subclase sunt moștenite de la o singură clasă de bază. adică mai mult de o clasă derivată este creată dintr-o singură clasă de bază.

Moștenirea ierarhică în C++

Sintaxă:-

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

Ieșire
This is a Vehicle This is a Vehicle>

5. Moștenire hibridă (virtuală). : Moștenirea hibridă este implementată prin combinarea mai multor tipuri de moștenire. De exemplu: combinarea moștenirii ierarhice și a moștenirii multiple.
Imaginea de mai jos arată combinația de moșteniri ierarhice și multiple:

Moștenirea hibridă în 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; }>

Ieșire
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;   } };    clasa B : public A { protejat: int b;   public: void get_b() { cout<< 'Enter the value of 'b' : ';  cin>>b;   } };  clasa C { protejat: int c;   public: void get_c() { cout<< 'Enter the value of c is : ';   cin>>c;   } };    clasa D : public B, public C { protejat: int d;   public: void mul() { get_a();   get_b();   get_c();   cout<< 'Multiplication of a,b,c is : ' < 

6. Un caz special de moștenire hibridă: moștenirea pe mai multe căi :
O clasă derivată cu două clase de bază și aceste două clase de bază au o clasă de bază comună se numește moștenire multipath. Ambiguitatea poate apărea în acest tip de moștenire.
Exemplu:

convertiți șirul în int
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 << '
'; }>

Ieșire
 a from ClassB : 10 a from ClassC : 100 b : 20 c : 30 d : 40>

În exemplul de mai sus, atât ClassB cât și ClassC moștenesc ClassA, ambele au o singură copie a ClassA. Cu toate acestea, Class-D moștenește atât ClassB, cât și ClassC, prin urmare, Class-D are două copii ale ClassA, una din ClassB și alta din ClassC.
Dacă trebuie să accesăm membrul de date al ClassA prin obiectul Class-D, trebuie să specificăm calea din care va fi accesat a, indiferent dacă este din ClassB sau ClassC, compilatorul bcoz nu poate diferenția între două copii ClassA în Clasa-D.

Există 2 moduri de a evita această ambiguitate:

1) Evitarea ambiguității folosind operatorul de rezoluție a domeniului: Folosind operatorul de rezoluție a domeniului, putem specifica manual calea din care va fi accesat membrul de date a, așa cum se arată în instrucțiunile 3 și 4, în exemplul de mai sus.

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


Notă: Totuși, există două copii ale ClassA în Class-D.
2) Evitarea ambiguității folosind clasa de bază virtuală:

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

Ieșire:

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

Conform exemplului de mai sus, clasa D are o singură copie a clasei A, prin urmare, instrucțiunea 4 va suprascrie valoarea lui a, dată în instrucțiunea 3.