Наследование классов — позволяет создавать производные классы (классы наследники), взяв за основу все методы и элементы базового класса (класса родителя).
#include
using
namespace
std;
class
FirstClass
// базовый класс
{
protected
:
// спецификатор доступа к элементу value
int
value;
public
:
FirstClass()
{
value = 0;
}
FirstClass(
int
input )
{
value = input;
}
void
show_value()
{
cout << value << endl;
}
};
class
SecondClass :
public
FirstClass
// производный класс
{
public
:
SecondClass() : FirstClass ()
// конструктор класса SecondClass
вызывает конструктор класса FirstClass
{}
SecondClass(
int
inputS) : FirstClass (inputS)
// inputS
передается в конструктор с параметром класса FirstClass
{}
void
ValueSqr ()
// возводит value в квадрат.
Без спецификатора доступа protected эта функция не могла бы изменить
значение value
{
value *= value;
}
};
int
main()
{
setlocale
(LC_ALL,
"rus"
);
FirstClass F_object(3);
// объект базового класса
cout <<
"value F_object = "
;
F_object.show_value();
SecondClass S_object(4);
// объект производного класса
cout <<
"value S_object = "
;
S_object.show_value();
// вызов метода базового класса
S_object.ValueSqr();
// возводим value в квадрат
cout <<
"квадрат value S_object = "
;
S_object.show_value();
//F_object.ValueSqr(); // базовый класс не имеет доступа
к методам производного класса
cout << endl;
return
0;
}
- Наследование — это определение производного класса, который может обращаться ко всем элементам и методам базового класса за исключением тех, которые находятся в поле
private
; - Синтаксис определения производного класса:
- class Имя_Производного_Класса : спецификатор доступа Имя_Базового_Класса { /*код*/ } ;
- Производный класс имеет доступ ко всем элементам и методам базового класса, а базовый класс может использовать только свои собственные элементы и методы.
- В производном классе необходимо явно определять свои конструкторы, деструкторы и перегруженные операторы присваивания из-за того, что они не наследуются от базового класса. Но их можно вызвать явным образом при определении конструктора, деструктора или перегрузки оператора присваивания производного класса, например таким образом (для конструктора): Конструктор_Производного_Класса (/*параметры*/) : Конструктор_Базового_Класса ( /*параметры*/) { } .
- Еще один важный момент при наследовании — перегруженные функции-методы класса потомка. Если в классе родителе и в его классах потомках встречаются методы с одинаковым именем, то для объектов класса потомка компилятор будет использовать методы именно класса потомка. Перегруженные методы класса потомка, могут вызывать методы класса родителя. В таком случае важно помнить, что необходимо правильно определить область действия с помощью оператора
::
.Иначе компилятор воспримет это, как вызов функцией самой себя. Наглядно, если бы мы перегрузили в классеSecondClass
функциюshow_value()
— это выглядело бы так:
1
2
3
4
5
|
void show_value() { if (value != 0) FirstClass :: show_value(); } |
Эта запись указывает компилятору — если значение value
не равно нулю — вызвать метод show_value()
класса FirstClass
. А он в свою очередь, отобразит это значение на экране.