Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Отчёт_Классы.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
49.82 Кб
Скачать

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

Наследование (inheritance) — это процесс, в ходе которого один объект может приобретать свойства другого. Он имеет большое значение, поскольку поддерживает концепцию классификации (classification).

Все знания организованы по принципу иерархической классификации. Например, антоновка (сорт яблока) относится к классу “яблоки”, который в свою очередь является частью класса “фрукты”, входящего в класс “пища".

Если бы классификации не существовало, мы не смогли бы точно описать свойства объектов. Однако при этом необходимо указывать только уникальные свойства объекта, позволяющие выделить его среди других объектов данного класса. Именно этот принцип лежит в основе механизма наследования, дающего возможность считать конкретный объект специфическим экземпляром более общей разновидности.

Класс, лежащий в основе иерархии, называется базовым (base class), а класс, наследующий свойства базового класса, — производным (derived class). Производные классы, в свою очередь, могут быть базовыми по отношению к другим классам.

Классы, находящиеся ближе к началу иерархии, объединяют в себе наиболее общие черты для всех нижележащих классов. По мере продвижения вниз по иерархии классы приобретают все больше конкретных черт.

Синтаксис:

class имя : [private | protected | public] базовый_класс

{ тело класса };

[private | protected | public] - ключи доступа.

Листинг 5: Пример наследования

#include <iostream>

#include <cstdio>

#define MAX_STR 3

#define STR_L 50

using namespace std;

class building {

int rooms;

int floors;

int area;

public:

void set_rooms(int num) {rooms = num;}

int get_rooms() {return rooms;}

void set_floors(int num){floors = num;}

int get_floors() {return floors;}

void set_area(int num){area = num;}

int get_area() {return area;}

};

// Класс house является производным от класса building

class house : public building {

int bedrooms;

int baths;

public:

void set_bedrooms(int num){bedrooms = num;}

int get_bedrooms(){return bedrooms;}

void set_baths(int num){bedrooms = num;}

int get_baths(){return baths;}

};

// Класс school также является производным от класса building

class school : public building {

int classrooms;

int offices;

public:

void set_classrooms(int num){classrooms = num;}

int get_classrooms(){return classrooms;}

void set_offices(int num){offices = num;}

int get_offices(){return offices;}

};

int main()

{

house h;

school s ;

h .set_rooms(12) ;

h.set_floors(3) ;

h.set_area(4500);

h .set_bedrooms(5);

h .set_baths(3);

cout << "В доме " << h.get_bedrooms();

cout << " спален\п";

s.set_rooms(200);

s.set_classrooms(180);

s.set_offices(5);

s.set_area(25000);

cout << "В школе " << s .get_classrooms();

cout << "классных комнат\п";

cout << "Ее площадь равна" << s .get_area();

return 0;

}

Результат:

В доме 3 спален

В школе 180 классных комнат

Ее площадь равна 25000

Protected

Закрытый член базового класса не доступен другим элементам программы, включая производный класс. Однако защищенные члены базового класса ведут себя иначе. При открытом наследовании защищенные члены базового класса становятся защищенными членами производного класса и,

следовательно, доступны остальным членам производного класса. Иными словами, защищенные члены класса по отношению к своему классу являются закрытыми и в то же время, могут наследоваться производным классом.

Ключ доступа

В базовом классе

В производном классе

private

private

нет

protected

private

public

private

protected

private

нет

protected

protected

public

protected

public

private

нет

protected

protected

public

public

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

Множественное наследование позволяет одному классу обладать свойствами двух и более родительских классов:

class А { ... };

class В { ... };

class С { ... };

class D: А, protected В, public С { ... }:

Множественное наследование применяется для того, чтобы обеспечить производный класс свойствами двух или более базовых. Чаще всего один из этих классов является основным, а другие обеспечивают некоторые дополнительные свойства, поэтому они называются классами подмешивания. По возможности классы подмешивания должны быть виртуальными и создаваться с помощью конструкторов без параметров, что позволяет избежать многих проблем, возникающих при ромбовидном наследовании (когда у базовых классов есть общий предок).

Листинг 6: Множественное наследование

#include <iostream>

using namespace std;

class basel {

protected:

int x;

public:

void showx() { cout << x << "\n"; }

} ;

class base2 {

protected:

int y;

public:

void showy() {cout << y << "\n";}

};

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

class derived: public basel, public base2 {

public:

void set(int i, int j) { x=i; y=j; }

} ;

int main()

{

derived ob;

ob.set(10, 20); // Эта функция принадлежит классу derived,

ob.showx(); // Эта функция принадлежит классу basel.

ob.showy(); // Эта функция принадлежит классу base2.

return 0;

}

Результат:

10

20

Конструкторы не наследуются, поэтому производный класс должен иметь собственные конструкторы. Порядок вызова конструкторов определяется приведенными ниже правилами.

  • Если в конструкторе производного класса явный вызов конструктора базового класса отсутствует, автоматически вызывается конструктор базового класса по умолчанию (то есть тот, который можно вызвать без параметров).

  • Для иерархии, состоящей из нескольких уровней, конструкторы базовых классов вызываются, начиная с самого верхнего уровня. После этого выполняются конструкторы тех элементов класса, которые являются объектами, в порядке их объявления в классе, а затем исполняется конструктор класса.

  • В случае нескольких базовых классов их конструкторы вызываются в порядке объявления.

  • Если конструктор базового класса требует указания параметров, он должен быть явным

  • образом вызван в конструкторе производного класса в списке инициализации

Вызов функций базового класса предпочтительнее копирования фрагментов кода из функций базового класса в функции производного.

Деструкторы не наследуются.

  • Если программист не описал в производном классе деструктор, он формируется по умолчанию и вызывает деструкторы всех базовых классов.

  • В отличие от конструкторов, при написании деструктора производного класса в нем не требуется явно вызывать деструкторы базовых классов, поскольку это будет сделано автоматически.

  • Для иерархии классов, состоящей из нескольких уровней, деструкторы вызываются в порядке, строго обратном вызову конструкторов: сначала вызывается деструктор класса, затем — деструкторы элементов класса, а потом деструктор базового класса.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]