Учебники

C ++ Наследование

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

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

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

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

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

class derived-class: access-specifier base-class

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

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

Live Demo

#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

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

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

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

Доступ общественности защищенный частный
Тот же класс да да да
Производные классы да да нет
Вне классов да нет нет

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

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

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

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

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

  • Открытое наследование. При получении класса из открытого базового класса открытые члены базового класса становятся открытыми членами производного класса, а защищенные члены базового класса становятся защищенными членами производного класса. Закрытые члены базового класса никогда не доступны напрямую из производного класса, но могут быть доступны через вызовы открытых и защищенных членов базового класса.

  • Защищенное наследование. При наследовании от защищенного базового класса открытые и защищенные члены базового класса становятся защищенными членами производного класса.

  • Частное наследование. При наследовании от частного базового класса открытые и защищенные члены базового класса становятся частными членами производного класса.

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

Защищенное наследование. При наследовании от защищенного базового класса открытые и защищенные члены базового класса становятся защищенными членами производного класса.

Частное наследование. При наследовании от частного базового класса открытые и защищенные члены базового класса становятся частными членами производного класса.

Множественное наследование

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

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

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

Live Demo

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

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