Основы наследования
Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy — урок 48 из 104.
Наследование позволяет классу перенимать свойства и поведение другого класса. Класс, от которого происходит наследование, называется базовым классом (или родительским), а класс, который наследует, называется производным классом (или дочерним).
Для создания производного класса используйте двоеточие, за которым следует спецификатор доступа и имя базового класса:
class Animal {
public:
std::string name;
void eat() {
std::cout << name << " is eating" << std::endl;
}
};
class Dog : public Animal {
public:
void bark() {
std::cout << name << " says woof!" << std::endl;
}
};Класс Dog теперь имеет доступ как к name, так и к eat() из Animal, а также к своему собственному методу bark(). В этом и заключается суть наследования: повторное использование существующего кода при добавлении новой функциональности.
Dog myDog;
myDog.name = "Buddy";
myDog.eat(); // Унаследовано от Animal
myDog.bark(); // Определено в DogКлючевое слово public перед Animal определяет тип наследования. Публичное наследование означает, что публичные члены базового класса остаются публичными в производном классе. Это наиболее распространенная форма, которая моделирует отношение «является» (is-a): Dog является Animal.
Задание
ЛегкоДавайте создадим простую иерархию транспортных средств, которая демонстрирует наследование в действии. Вы создадите базовый класс Vehicle и производный класс Motorcycle, который расширяет его специализированным поведением.
Вы организуете свой код в трех файлах:
Vehicle.h: Определите базовый классVehicleс:- Публичным членом
std::string brand - Публичным членом
int year - Публичным методом
displayInfo(), который выводит марку и год выпуска транспортного средства в формате:Brand: <brand>, Year: <year>
- Публичным членом
Motorcycle.h: Определите классMotorcycle, который публично наследуется отVehicle. Этот производный класс должен добавить:- Публичный член
int engineCCдля объема двигателя - Публичный метод
revEngine(), который выводит:<brand> goes vroom vroom!
Класс
Motorcycleавтоматически унаследуетbrand,yearиdisplayInfo()отVehicle.- Публичный член
main.cpp: Считайте три входных значения (каждое на отдельной строке):- Название марки (строка)
- Год (целое число)
- Объем двигателя в СС (целое число)
Создайте объект
Motorcycle, установите его унаследованные члены (brandиyear), а также его собственный членengineCC. Затем продемонстрируйте наследование, вызвав как унаследованный метод, так и метод, специфичный для мотоцикла.Формат вывода:
Brand: <brand>, Year: <year> Engine: <engineCC>cc <brand> goes vroom vroom!
Например, при входных данных Harley, 2022 и 1200:
Brand: Harley, Year: 2022
Engine: 1200cc
Harley goes vroom vroom!Не забудьте включить guard-заголовки в ваши заголовочные файлы и использовать #include "Vehicle.h" в заголовке Motorcycle для доступа к базовому классу.
Шпаргалка
Наследование позволяет классу приобретать свойства и поведение другого класса. Класс, от которого происходит наследование, называется базовым классом (родительским), а класс, который наследует, — производным классом (дочерним).
Чтобы создать производный класс, используйте двоеточие, за которым следует спецификатор доступа и имя базового класса:
class Animal {
public:
std::string name;
void eat() {
std::cout << name << " is eating" << std::endl;
}
};
class Dog : public Animal {
public:
void bark() {
std::cout << name << " says woof!" << std::endl;
}
};Производный класс имеет доступ к публичным членам базового класса, а также к своим собственным членам:
Dog myDog;
myDog.name = "Buddy";
myDog.eat(); // Унаследовано от Animal
myDog.bark(); // Определено в DogКлючевое слово public указывает на публичное наследование, что означает, что публичные члены базового класса остаются публичными в производном классе. Это моделирует отношение «является» (is-a).
Попробуйте сами
#include <iostream>
#include <string>
#include "Motorcycle.h"
using namespace std;
int main() {
string brand;
int year;
int engineCC;
cin >> brand;
cin >> year;
cin >> engineCC;
// TODO: Создайте объект Motorcycle
// TODO: Установите значения его полей brand, year и engineCC
// TODO: Вызовите displayInfo(), чтобы показать унаследованную информацию
// TODO: Выведите информацию о двигателе в формате: Engine: <engineCC>cc
// TODO: Вызовите revEngine(), чтобы продемонстрировать специфическое поведение мотоцикла
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыСборка и компиляция C++Заголовочные файлы и файлы исходного кодаПространства имен и область видимостиВведение в ООП на C++Классы и объектыУказатель 'this'Методы (функции-члены)Атрибуты (члены данных)Основы конструкторов и деструкторовИтоги — Простой калькулятор4Свойства классов
Члены экземпляра против статическихГеттеры и сеттерыКонстантные функции-членыКлючевое слово mutableСтатические методы и переменныеДружественные функции и классыИтоги — Менеджер банковских счетов7Наследование
Основы наследованияУровни доступа при наследованииПорядок вызова конструкторов и деструкторовПереопределение методовВиртуальные функции и VTableМножественное наследованиеВиртуальное наследованиеИтоги — Иерархия сотрудников10Обзор STL
Обзор и философия STLКонтейнеры STLИтераторыАлгоритмы STLФункторы и лямбда-выраженияИтоги: частота слов13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonFactory и Abstract FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy2Управление памятью
Стек и кучаУказатели и ссылкиДинамическая память (new/delete)Умные указатели в C++RAII в C++Итоги — Менеджер динамического массива5Инкапсуляция
Спецификаторы доступа в C++Спецификаторы доступа: подробный разборСокрытие данныхStruct против ClassВложенные и внутренние классыИтоги — Система учета студентов8Полиморфизм
Полиморфизм компиляции и времени выполненияПерегрузка функцийВиртуальные функции: повторениеЧистые виртуальные функцииАбстрактные классыПроектирование интерфейсов на C++Dynamic Casting и RTTIИтоги: Калькулятор фигур11Продвинутые концепции ООП
Композиция против наследованияМиксины через CRTPИдиома PimplСтирание типовEnum Classes и строгая типизацияОбработка исключений в ООППользовательские иерархии исключений14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикRAII как паттерн3Конструкторы и деструкторы
Конструктор по умолчаниюПараметризованный конструкторКонструктор копированияКонструктор перемещенияСписки инициализации конструктораДелегирующие конструкторыГлубокое погружение в деструкторыПравило трех / пяти / нуляПовторение — класс String6Перегрузка операторов
Введение в перегрузку операторовПерегрузка арифметических операторовПерегрузка операторов сравненияОператоры потоковПерегрузка оператора присваиванияПерегрузка операторов [] и ()Операторы преобразования типовИтоги — класс Matrix9Шаблоны
Шаблоны функцийШаблоны классовСпециализация шаблоновВариативные шаблоныОсновы SFINAE и Type TraitsИтоги — Обобщенный контейнер