logo

Herència en C++

La capacitat d'a classe s'anomena derivar propietats i característiques d'una altra classe Herència . L'herència és una de les característiques més importants de la programació orientada a objectes.

L'herència és una característica o un procés en el qual es creen noves classes a partir de les classes existents. La nova classe creada s'anomena classe derivada o classe fill i la classe existent es coneix com a classe base o classe pare. Ara es diu que la classe derivada s'hereta de la classe base.



Quan diem que la classe derivada hereta la classe base, vol dir que la classe derivada hereta totes les propietats de la classe base, sense canviar les propietats de la classe base i pot afegir noves característiques a la seva. Aquestes noves característiques de la classe derivada no afectaran la classe base. La classe derivada és la classe especialitzada per a la classe base.

  • Subclasse: La classe que hereta propietats d'una altra classe s'anomena subclasse o classe derivada.
  • Super Classe: La classe les propietats de la qual són heretades per una subclasse s'anomena Classe base o Superclasse.

L'article està dividit en els següents subtemes:

  • Per què i quan utilitzar l'herència?
  • Modes d'herència
  • Tipus d'herència

Per què i quan utilitzar l'herència?

Considereu un grup de vehicles. Heu de crear classes per a autobusos, cotxes i camions. Els mètodes fuelAmount(), capacity(), applyBrakes() seran els mateixos per a les tres classes. Si creem aquestes classes evitant l'herència, hem d'escriure totes aquestes funcions en cadascuna de les tres classes tal com es mostra a la figura següent:



herència en C++

dividit per cadena java

Podeu veure clarament que el procés anterior provoca la duplicació del mateix codi 3 vegades. Això augmenta les possibilitats d'error i redundància de dades. Per evitar aquest tipus de situacions, s'utilitza l'herència. Si creem una classe Vehicle i hi escrivim aquestes tres funcions i heretem la resta de classes de la classe de vehicle, llavors podem evitar la duplicació de dades i augmentar la reutilització. Mireu el diagrama següent en què les tres classes s'hereten de la classe del vehicle:

aplicació d'herència en C++



Utilitzant l'herència, hem d'escriure les funcions només una vegada en lloc de tres, ja que hem heretat la resta de les tres classes de la classe base (Vehicle).
Implementació de l'herència en C++ : Per crear una subclasse que s'hereta de la classe base hem de seguir la sintaxi següent.

Classes derivades: Una classe derivada es defineix com la classe derivada de la classe base.
Sintaxi :

class :  {  //body }>

On
class — paraula clau per crear una nova classe
derived_class_name — nom de la nova classe, que heretarà la classe base
especificador d'accés: privat, públic o protegit. Si no s'especifica cap, s'utilitza PRIVAT per defecte
nom-classe-base — nom de la classe base
Nota : Una classe derivada no hereta accés als membres de dades privades. Tanmateix, hereta un objecte pare complet, que conté tots els membres privats que aquesta classe declari.

Exemple:
1. classe ABC : XYZ privada //derivació privada
{ }
2. classe ABC : XYZ pública //derivació pública
{ }
3. classe ABC : XYZ protegit //derivació protegida
{ }
4. classe ABC: XYZ //derivació privada per defecte
{ }

Nota:

o Quan una classe base és heretada de manera privada per la classe derivada, els membres públics de la classe base esdevenen els membres privats de la classe derivada i, per tant, només es pot accedir als membres públics de la classe base mitjançant les funcions membre de la classe derivada. Són inaccessibles als objectes de la classe derivada.
o D'altra banda, quan la classe base és heretada públicament per la classe derivada, els membres públics de la classe base també esdevenen els membres públics de la classe derivada. Per tant, els membres públics de la classe base són accessibles pels objectes de la classe derivada així com per les funcions membre de la classe derivada.

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

Sortida:

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

Sortida:

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(aquest->nom,n);  } void Persona::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; }>

Sortida
Child id is: 7 Parent id is: 91>

Al programa anterior, la classe 'Fill' s'hereta públicament de la classe 'Parent', de manera que els membres de dades públiques de la classe 'Parent' també seran heretats per la classe 'Fill'.
Modes d'herència: Hi ha 3 modes d'herència.

  1. Modalitat pública : Si derivem una subclasse d'una classe base pública. Aleshores, el membre públic de la classe base esdevindrà públic a la classe derivada i els membres protegits de la classe base passaran a estar protegits a la classe derivada.
  2. Mode protegit : Si derivem una subclasse d'una classe base protegida. Aleshores, tant els membres públics com els membres protegits de la classe base quedaran protegits a la classe derivada.
  3. Mode privat : Si derivem una subclasse d'una classe base Privada. Aleshores, tant els membres públics com els membres protegits de la classe base es convertiran en Privats a la classe derivada.

Nota: No es pot accedir directament als membres privats de la classe base a la classe derivada, mentre que es pot accedir directament als membres protegits. Per exemple, les classes B, C i D contenen totes les variables x, y i z de l'exemple següent. És només una qüestió d'accés.

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


La taula següent resumeix els tres modes anteriors i mostra l'especificador d'accés dels membres de la classe base a la subclasse quan es deriva en els modes públic, protegit i privat:

decodificació javascript base64

Tipus d'herència: -

  1. Herència única
  2. Herència multinivell
  3. Herència múltiple
  4. Herència jeràrquica
  5. Herència híbrida

Tipus d'herència en C++

1. Herència única : En l'herència única, una classe només pot heretar d'una classe. és a dir, una subclasse només l'hereta una classe base.

Herència única en C++

Sintaxi :

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

Sortida
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<Sortida: - Introduïu el valor de A= 3 3 Introduïu el valor de B= 5 5 Producte de 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. Herència múltiple: L'herència múltiple és una característica de C++ on una classe pot heretar de més d'una classe. és a dir un subclasse s'hereta de més d'un classe base .

Herència múltiple en C++

Sintaxi :

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

Aquí, el nombre de classes base estarà separat per una coma (', ') i s'ha d'especificar el mode d'accés per a cada classe base.

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

Sortida
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<Per saber-ne més, consulteu l'article Herències múltiples .


3. Herència multinivell : En aquest tipus d'herència, es crea una classe derivada a partir d'una altra classe derivada.

Herència multinivell en C++

mamta kulkarni

Sintaxi: -

nick pulos llamp negre
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; }>

Sortida
This is a Vehicle Objects with 4 wheels are vehicles Car has 4 Wheels>

4. Herència jeràrquica : En aquest tipus d'herència, més d'una subclasse s'hereta d'una sola classe base. és a dir, es crea més d'una classe derivada a partir d'una sola classe base.

Herència jeràrquica en C++

Sintaxi: -

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

Sortida
This is a Vehicle This is a Vehicle>

5. Herència híbrida (virtual). : L'herència híbrida s'implementa combinant més d'un tipus d'herència. Per exemple: combinació de l'herència jeràrquica i l'herència múltiple.
La imatge següent mostra la combinació d'herències jeràrquiques i múltiples:

Herència híbrida en 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; }>

Sortida
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;   }};    classe B : públic A { protegit: int b;   públic: void get_b() { cout<< 'Enter the value of 'b' : ';  cin>>b;   }};  classe C { protegit: int c;   públic: void get_c() { cout<< 'Enter the value of c is : ';   cin>>c;   }};    classe D: públic B, públic C { protegit: int d;   públic: void mul() { get_a();   get_b();   get_c();   cout<< 'Multiplication of a,b,c is : ' < 

6. Un cas especial d'herència híbrida: l'herència multipath :
Una classe derivada amb dues classes base i aquestes dues classes base tenen una classe base comuna s'anomena herència multipath. En aquest tipus d'herència pot sorgir ambigüitat.
Exemple:

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

Sortida
 a from ClassB : 10 a from ClassC : 100 b : 20 c : 30 d : 40>

A l'exemple anterior, tant ClassB com ClassC hereten ClassA, tots dos tenen una única còpia de ClassA. Tanmateix, Class-D hereta tant ClassB com ClassC, per tant, Class-D té dues còpies de ClassA, una de ClassB i una altra de ClassC.
Si necessitem accedir al membre de dades de ClassA a través de l'objecte de Class-D, hem d'especificar el camí des del qual s'accedirà a a, ja sigui de ClassB o ClassC, el compilador bcoz no pot diferenciar entre dues còpies de ClassA en Classe D.

Hi ha 2 maneres d'evitar aquesta ambigüitat:

1) Evitar l'ambigüitat mitjançant l'operador de resolució d'abast: Mitjançant l'operador de resolució d'àmbit podem especificar manualment la ruta des del qual s'accedirà al membre de dades a, tal com es mostra a les declaracions 3 i 4, a l'exemple anterior.

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


Nota: Tot i així, hi ha dues còpies de ClassA a Class-D.
2) Evitar l'ambigüitat utilitzant la classe base 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 << '
'; }>

Sortida:

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

Segons l'exemple anterior, Class-D només té una còpia de ClassA, per tant, la declaració 4 sobreescriurà el valor de a, donat a la declaració 3.