Herança C ++

Um dos conceitos mais importantes na programação orientada a objetos é o de herança. A herança nos permite definir uma classe em termos de outra classe, o que torna mais fácil criar e manter um aplicativo. Isso também oferece uma oportunidade de reutilizar a funcionalidade do código e o tempo de implementação rápido.

Ao criar uma classe, em vez de escrever membros de dados e funções de membro completamente novos, o programador pode designar que a nova classe deve herdar os membros de uma classe existente. Esta classe existente é chamada debase classe, e a nova classe é chamada de derived classe.

A ideia de herança implementa o is arelação. Por exemplo, mamífero IS-A animal, cão IS-A mamífero, portanto cão IS-A animal também e assim por diante.

Classes de base e derivadas

Uma classe pode ser derivada de mais de uma classe, o que significa que pode herdar dados e funções de várias classes base. Para definir uma classe derivada, usamos uma lista de derivação de classe para especificar a (s) classe (s) base. Uma lista de derivação de classe nomeia uma ou mais classes base e tem a forma -

class derived-class: access-specifier base-class

Onde o especificador de acesso é um dos public, protected, ou private, e classe base é o nome de uma classe definida anteriormente. Se o especificador de acesso não for usado, ele será privado por padrão.

Considere uma classe base Shape e sua classe derivada Rectangle como segue -

#include <iostream>
 
using namespace std;

// Base class
class Shape {
   public:
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }
      
   protected:
      int width;
      int height;
};

// Derived class
class Rectangle: public Shape {
   public:
      int getArea() { 
         return (width * height); 
      }
};

int main(void) {
   Rectangle Rect;
 
   Rect.setWidth(5);
   Rect.setHeight(7);

   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

Total area: 35

Controle de acesso e herança

Uma classe derivada pode acessar todos os membros não privados de sua classe base. Portanto, os membros da classe base que não devem ser acessíveis às funções de membro das classes derivadas devem ser declarados privados na classe base.

Podemos resumir os diferentes tipos de acesso de acordo com - quem pode acessá-los da seguinte maneira -

Acesso público protegido privado
Mesma classe sim sim sim
Classes derivadas sim sim não
Aulas externas sim não não

Uma classe derivada herda todos os métodos da classe base com as seguintes exceções -

  • Construtores, destruidores e construtores de cópia da classe base.
  • Operadores sobrecarregados da classe base.
  • As funções de amigo da classe base.

Tipo de Herança

Ao derivar uma classe de uma classe base, a classe base pode ser herdada por meio de public, protected ou privateherança. O tipo de herança é especificado pelo especificador de acesso conforme explicado acima.

Dificilmente usamos protected ou private herança, mas publicherança é comumente usada. Ao usar diferentes tipos de herança, as seguintes regras são aplicadas -

  • Public Inheritance - Ao derivar uma classe de um public classe base, public membros da classe base se tornam public membros da classe derivada e protected membros da classe base se tornam protectedmembros da classe derivada. De uma classe baseprivate membros nunca são acessíveis diretamente de uma classe derivada, mas podem ser acessados ​​por meio de chamadas para o public e protected membros da classe base.

  • Protected Inheritance - Ao derivar de um protected classe base, public e protected membros da classe base se tornam protected membros da classe derivada.

  • Private Inheritance - Ao derivar de um private classe base, public e protected membros da classe base se tornam private membros da classe derivada.

Herança múltipla

Uma classe C ++ pode herdar membros de mais de uma classe e aqui está a sintaxe estendida -

class derived-class: access baseA, access baseB....

Onde o acesso é um de public, protected, ou privatee seriam fornecidos para cada classe base e serão separados por vírgula, conforme mostrado acima. Vamos tentar o seguinte exemplo -

#include <iostream>
 
using namespace std;

// Base class Shape
class Shape {
   public:
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }
      
   protected:
      int width;
      int height;
};

// Base class PaintCost
class PaintCost {
   public:
      int getCost(int area) {
         return area * 70;
      }
};

// Derived class
class Rectangle: public Shape, public PaintCost {
   public:
      int getArea() {
         return (width * height); 
      }
};

int main(void) {
   Rectangle Rect;
   int area;
 
   Rect.setWidth(5);
   Rect.setHeight(7);

   area = Rect.getArea();
   
   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   // Print the total cost of painting
   cout << "Total paint cost: $" << Rect.getCost(area) << endl;

   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

Total area: 35
Total paint cost: $2450