printНаследование

printОтношение наследования между классами

Механизм наследования позволяет создавать новые классы на основе существующих путем расширения или изменения их структуры и поведения. Наследование не следует путать с агрегацией (отношением часть-целое) и использованием:
  • водитель `→` автомобиль: водитель сам никуда не может поехать, нет связей между их свойствами, но только водитель может выполнять действия над автомобилем, следовательно, это отношение использования;
  • двигатель `→` автомобиль: двигатель самостоятельно никуда не может поехать (нет колес), характеристики двигателя являются частью свойств автомобиля (максимальная скорость, мощность, тип топлива, его расход и т.п.), следовательно, это отношение агрегации;
  • грузовик `→` автомобиль: грузовик имеет такие же свойства и поведение, как автомобиль, добавляется новый элемент – кузов и возможность перевозить грузы, следовательно, это отношение наследования.

После имени производного класса можно написать символ : и указать список базовых классов через запятую. Перед именем базового класса можно указать спецификатор доступа для наследуемых элементов. По умолчанию для базовых классов в классах, объявленных с помощью struct, устанавливается спецификатор доступа public, а в классах, объявленных с помощью class, – private.

Можно изменить уровень доступа к отдельным наследуемым элементам класса (кроме закрытых элементов базового класса, доступа к которым из производного класса нет), используя using.
class A {
public:
  void f();
  void g();
};
class B : protected A {
public:
  using A::g; // g - public, f - protected
};
С помощью using можно в производном класса добавить метод к набору методов с тем же именем в базовом классе:
class A {
public:
  void f();
};
class B1 : public A {
public:
  void f(int); 
};
class B2 : public A {
public:
  void f(int); 
  using A::f;  
};
int main()
{ B1 b1;
  b1.f(); // Ошибка, метод перекрыт
  B2 b2;
  b2.f(); // Ok, метод перегружен
}
Если производный класс не имеет собственных полей или всем им задано значение по умолчанию, можно наследовать конструкторы базового класса с помощью using:
class A {
  int x,y;
public:
  A(int x, int y):x(x),y(y){}
  A():x(0),y(0){}
};
class B : public A {
  int z=0;
public:
  using A::A; // будут добавлены B(int x, int y) и B()
};
int main()
{ B b1(2,3);
  B b2;
}
loading