Как видно по результатам выполнения этой программы, основное достоинство наследования состоит в том, что оно позволяет создать базовый класс, который затем можно включить в состав более специализированных классов. Таким образом, каждый производный класс может служить определенной цели и при этом оставаться частью общей классификации.
И еще. Обратите внимание на то, что оба класса truck
и automobile включают функцию-член show(), которая отображает информацию об объекте. Эта функция демонстрирует еще один аспект объектно-ориентированного программирования — полиморфизм. Поскольку каждая функция show() связана с собственным классом, компилятор может легко "понять", какую именно функцию нужно вызвать для данного объекта.После ознакомления с общей процедурой наследования одним классом другого можно перейти и к деталям этой темы.
Управление доступом к членам базового класса
Если один класс наследует другой, члены базового класса становятся членами производного. Статус доступа членов базового класса в производном классе определяется спецификатором доступа, используемым для наследования базового класса. Спецификатор доступа базового класса выражается одним из ключевых слов: public
, private или protected. Если спецификатор доступа не указан, то по умолчанию используется спецификатор private, если речь идет о наследовании типа class. Если же наследуется тип struct, то при отсутствии явно заданного спецификатора доступа по умолчанию используется спецификатор public. Рассмотрим рамификацию (разветвление) использования спецификаторов public или private. (Спецификатор protected описан в следующем разделе.)Если базовый класс наследуется как public-класс, его public-члены становятся public-членами производного класса.
Если базовый класс наследуется как publie
-класс, все его public-члены становятся public-членами производного класса. Во всех случаях private-члены базового класса остаются закрытыми в рамках этого класса и не доступны для членов производного. Например, в следующей программе public-члены класса base становятся public-членами класса derived. Следовательно, они будут доступны и для других частей программы.
#include
using namespace std;
class base {
int i, j;
public:
void set (int a, int b) { i = a; j = b; }
void show() { cout << i << " " << j << "\n"; }
};
class derived : public base {
int k;
public:
derived(int x) { k = x; }
void showk() { cout << k << "\n"; }
};
int main()
{
derived ob(3);
ob.set(1, 2); // доступ к членам класса base
ob.show(); // доступ к членам класса base
ob.showk(); // доступ к члену класса derived
return 0;
}
Поскольку функции set()
и show() (члены класса base) унаследованы классом derived как public-члены, их можно вызывать для объекта типа derived в функции main(). Поскольку члены данных i и j определены как private-члены, они остаются закрытыми в рамках своего класса base.Если базовый класс наследуется как private-класс, его public-члены становятся private-членами производного класса.
Противоположностью открытому (public
) наследованию является закрытое (private). Если базовый класс наследуется как private-класс, все его public-члены становятся private-членами производного класса. Например, следующая программа не скомпилируется, поскольку обе функции set() и show() теперь стали private-членами класса derived, и поэтому их нельзя вызывать из функции main().
// Эта программа не скомпилируется.
#include
using namespace std;
class base {
int i, j;
public:
void set (int a, int b) { i = a; j = b; }
void show() { cout << i << " " << j << "\n"; }
};
// Открытые члены класса base теперь становятся
// закрытыми членами класса derived.
class derived : private base {
int k;
public:
derived(int x) { k = x; }
void showk() { cout << k << "\n"; }
};
int main()
{
derived ob (3);