Одним из наиболее важных понятий объектно-ориентированного программирования является наследование. Наследование позволяет нам определить класс в терминах другого класса, что упрощает создание и обслуживание приложения. Это также дает возможность повторно использовать функциональность кода и быстрое время выполнения.

При создании класса вместо написания совершенно новых членов данных и функций-членов программист может обозначить, что новый класс должен наследовать членов существующего класса. Этот существующий класс называется базовым классом, а новый класс называется производным .

Идея наследования реализует это отношения. Например, млекопитающее животное IS-A, млекопитающее собаки IS-A, следовательно, животное IS-A собаки и так далее.

Базовые и производные классы

Класс может быть получен из более чем одного класса, что означает, что он может наследовать данные и функции из нескольких базовых классов. Чтобы определить производный класс, мы используем список производных классов, чтобы указать базовый класс (es). Список дериваций классов называет один или несколько базовых классов и имеет форму -

class derived-class: access-specifier base-class

Если спецификатор доступа является одним из общедоступных, защищенных или закрытых , а базовым классом является имя ранее определенного класса. Если спецификатор доступа не используется, он по умолчанию является закрытым.

Рассмотрим базовый класс Shape и его производный класс Rectangle следующим образом:

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

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Total area: 35

Контроль доступа и наследование

Производный класс может получить доступ ко всем не-частным членам своего базового класса. Таким образом, члены базового класса, которые не должны быть доступны для функций-членов производных классов, должны быть объявлены частными в базовом классе.

Мы можем суммировать различные типы доступа в зависимости от того, кто может получить к ним доступ следующим образом:

Access

public

protected

private

Same class

да

да

да

Derived classes

да

да

нет

Outside classes

да

нет

нет

Производный класс наследует все методы базового класса со следующими исключениями:

  • Конструкторы, деструкторы и конструкторы копирования базового класса.
  • Перегруженные операторы базового класса.
  • Друг-функции базового класса.

Тип наследования

При выводе класса из базового класса базовый класс может наследоваться через общедоступное, защищенное или частное наследование. Тип наследования определяется спецификатором доступа, как описано выше.

Едва ли мы использовать защищенный или частное наследование, но общественное наследование обычно используется. При использовании другого типа наследования применяются следующие правила:

  • Public Inheritance - При выводе класса из общедоступногобазового класса публичные члены базового класса становятся общедоступными членами производного класса, а защищенныечлены базового класса становятся защищенными членами производного класса. Частные члены базового класса никогда не доступны непосредственно из производного класса, но могут быть доступны через вызовы для публичных и защищенных членов базового класса.
  • Protected legacy. При получении из защищенногобазового класса общедоступные и защищенные члены базового класса становятся защищенными членами производного класса.
  • Private Inheritance - При получении из частного базового класса общедоступные и защищенные члены базового класса становятся частными членами производного класса.

Многократное наследование

Класс C ++ может наследовать членов из более чем одного класса, и вот расширенный синтаксис -

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

Если доступ является одним из общедоступных, защищенных или закрытых и будет предоставлен для каждого базового класса, они будут разделены запятой, как показано выше. Попробуем следующий пример -

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

Когда приведенный выше код компилируется и выполняется, он производит следующий результат:

Total area: 35
Total paint cost: $2450