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

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

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

Наследование представляет собой отношение«является». Например, млекопитающие — это животные, собаки — млекопитающие, следовательно, собаки — животные, и так далее.

Код выглядит следующим образом:

// Базовый класс
class Animal {
    // функция eat()
    // функция sleep()
};


// производный класс
class Dog : public Animal {
    // функция bark()
};

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

Класс может быть произведён от нескольких классов, что означает, что он может наследовать данные и функции от нескольких базовых классов. Чтобы определить производный класс, мы используем список наследования для указания базовых классов. Список наследования содержит имена одного или нескольких базовых классов в следующей форме:

class derived-class: access-specifier base-class

Здесь модификатор доступа access-specifier — этоpublic、protectedилиprivateСреди них base-class — имя ранее определённого класса. Если модификатор доступа access-specifier не используется, по умолчанию используется private.

Предположим, есть базовый классShape,Rectangleявляется его производным классом, как показано ниже:

Пример

#include <iostream> using namespace std; // Базовый класс class Shape { public: void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // Производный класс class Rectangle: public Shape { public: int getArea() { return (width * height); } }; int main(void) { Rectangle Rect; Rect.setWidth(5); Rect.setHeight(7); // Вывести площадь объекта cout << "Общая площадь: " << Rect.getArea() << endl; return 0; }

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

Total area: 35

Управление доступом и наследование

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

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

Посетитьpublicprotectedprivate
тот же классдадада
производный классдаданет
внешние классыданетнет

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

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

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

Когда класс является производным от базового класса, базовый класс может быть унаследован какpublic、protectedили private— существует несколько типов. Тип наследования задаётся модификатором доступа access-specifier, объяснённым выше.

Мы редко используем наследованиеprotectedили private, обычно используемpublicНаследование. При использовании различных типов наследования следуйте следующим правилам:

  • Открытое наследование (public):Когда класс является производным отpublicбазового класса, егоpublicчлены также принадлежат производному классу.publicчлены,protectedчлены базового класса также принадлежат производному классу.protectedчлены, базового классаprivateчленам производный класс не может обращаться напрямую, но к ним можно получить доступ, вызвавpublicиprotectedчлены базового класса.
  • Защищённое наследование (protected):Когда класс является производным отprotectedбазового класса, егоpublicиprotectedчлены станут членами производного класса.protectedчлены.
  • Закрытое наследование (private):Когда класс является производным отprivateбазового класса, егоpublicиprotectedчлены станут членами производного класса.privateчлены.

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

Множественное наследование означает, что подкласс может иметь несколько родительских классов и наследует характеристики нескольких родительских классов.

Классы C++ могут наследовать члены от нескольких классов; синтаксис следующий:

class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,…
{
<派生类类体>
};

где способ наследования с модификатором доступа — этоpublic、protectedилиprivateОдин из них используется для изменения каждого базового класса, а базовые классы разделяются запятыми, как показано выше. Теперь давайте вместе рассмотрим следующий пример:

Пример

#include <iostream> using namespace std; // Базовый класс Shape class Shape { public: void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // Базовый класс PaintCost class PaintCost { public: int getCost(int area) { return area * 70; } }; // Производный класс 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(); // Вывод площади объекта cout << "Общая площадь: " << Rect.getArea() << endl; // Вывод общей стоимости cout << "Общая стоимость краски: $" << Rect.getCost(area) << endl; return 0; }

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

Total area: 35
Total paint cost: $2450
Другие расширения