Практикум по объектно-ориентированному программированию на базе языка с++ Учебно-методическое пособие



Pdf көрінісі
бет22/44
Дата21.02.2024
өлшемі0.49 Mb.
#492719
түріПрактикум
1   ...   18   19   20   21   22   23   24   25   ...   44
ООП С

Контрольные вопросы 
 
1. Что такое статические элементы класса? Чем они отличаются от обыч-
ных элементов? Зачем используются? 
2. Как происходит инициализация статических элементов класса? 
3. Можно ли использовать указатель this в статических методах? 
4. Какими способами можно вызвать статический метод? 
 
 


39 
ЛАБОРАТОРНАЯ РАБОТА № 9. 
ПРОИЗВОДНЫЕ КЛАССЫ, НАСЛЕДОВАНИЕ 
Ключевые слова: наследование, базовый класс, виртуальный ме-
тод, полиморфизм, производный класс, абстрактный класс, чисто вирту-
альный метод, множественное наследование, виртуальное наследование 
виртуальный деструктор. 
Цель: Познакомится с наследованием, видами наследования, вир-
туальными методами, абстрактными классами и множественным насле-
дованием. 
Наследование – это такое отношение между классами, когда один 
класс частично или полностью повторяет структуру и поведение другого 
класса (одиночное наследование) или других (множественное наследова-
ние) классов. Наследование устанавливает между классами иерархию 
«общее-частное». 
Связи наследования также называют обобщениями (generalization
и изображают в виде стрелок от класса-потомка к классу-предку.
Рассмотрим пример – учет сотрудников организации. Каждый со-
трудник – это, прежде всего, человек. Студент, работник, руководитель – 
частные случаи объекта «человек», определяющего общие характери-
стики для всех своих разновидностей. Организация этих понятий в иерар-
хию позволяет избежать повторения кода и обращаться с объектами про-
изводных классов как с объектами базового.
Возьмем за основу иерархии класс Person, немного изменив его 
структуру ради соответствия концепции наследования. Поскольку для 
всех объектов кадровой структуры требуется знать имя, фамилию,
а также год рождения для определения возраста, объявим данные атри-
буты как protected, заменив заодно тип представления имени и отчества 
на более удобный в работе тип String
 
class Person

public: 
void set_year(int value); 
void set_sirname(string & value); 
void set_name(string & value); 
 
const string & get_name() const; 
const int get_year() const; 
const string & get_sirname() const; 
40 
protected: 
String name; 
String sirname; 
int year; 
}; 
Работник (Employee) отличается от просто человека (Person) тем, 
что работает в некотором подразделении (Department) и получает опре-
деленную заработную плату. Руководитель (Manager), являясь, в свою 
очередь работником предприятия, отвечает за определенную группу под-
чиненных и может получать заработную плату, складывающуюся из
основной ставки и надбавки в виде процента от заработной платы своих 
работников. 
Выделять новый класс из существующего стоит лишь тогда, когда 
он знает или делает то, чего не знает и не делает объект базового класса. 
Это означает присутствие в производном классе атрибута или метода,
неприменимого для объектов класса-предка. 
Механизм наследования классов позволяет строить иерархии, в ко-
торых производные классы получают элементы родительских, или базо-
вых, классов и могут дополнять их или изменять их свойства. Классы, 
находящиеся ближе к началу иерархии, объединяют в себе наиболее
общие черты для всех нижележащих классов. По мере продвижения вниз 
по иерархии классы все больше приобретают конкретные особенности: 
Конструкторы не наследуются, поэтому производный класс должен 
иметь собственные конструкторы. 
Порядок вызова конструкторов: 
 Если в конструкторе производного класса явный вызов конструктора 
базового класса отсутствует, автоматически вызывается конструктор 
базового класса по умолчанию (без параметров). 
 Для иерархии, состоящей из нескольких уровней, конструкторы базо-
вых классов вызываются, начиная с самого верхнего уровня. После 
этого выполняются конструкторы тех элементов класса, которые
являются объектами, в порядке их объявления в классе, а затем испол-
няется конструктор класса. 
 В случае нескольких базовых классов их конструкторы вызываются
в порядке объявления. 
Операция присваивания не наследуется и, поэтому ее также требу-
ется явно определить. 


41 
Деструкторы не наследуются, и если программист не описал в про-
изводном классе деструктор, он формируется по умолчанию и вызывает 
деструкторы всех базовых классов. 
В отличие от конструкторов, при написании деструктора произ-
водного класса в нем не требуется явно вызывать деструкторы базовых 
классов, это будет сделано автоматически. 
Для иерархии классов, состоящей из нескольких уровней, деструк-
торы вызываются в порядке, строго обратном вызову конструкторов: сна-
чала вызывается деструктор класса, затем – деструкторы элементов 
класса, а потом деструктор базового класса.
Доступ к объектам иерархии классов лучше всего осуществляется 
через указатели на базовый тип. При наследовании со спецификатором 
public такому указателю можно присваивать адрес любого производного 
класса. Проблема заключается в том, что компилятор не будет знать,
с каким именно классом связан указатель. Например, мы имеем в наличии 
трех работников: двух подчиненных (A и B) и их руководителя C, состав-
ляющих множество E. Им назначена зарплата в 3300, 4400 и 5500 рублей 
соответственно. У нас стоит задача представить фактические доходы
работников, которые будут определяться не только окладом. 
 
void main() 

Employee A, B; 
Manager C;
Employee* p[3]; 
p[0] = & A; p[1] = & B; p[2] = & C; 
 
C.Employers.push_back(& A); 
C.Employers.push_back(& B); 
 
p[0]->set_salary(3300); 
p[1]->set_salary(4400); 
p[2]->set_salary(5500); 
 
for (i = 0; i < 3; i++) 

cout << p[i]->get_salary() << endl; 


42 
Отметим, что во время компиляции не будет известно, на какой 
объект указывает p[i], следовательно, класс будет определяться по типу 
указателя. Соответственно будет выбран и правильный метод для вычис-
ления заработной платы. 
В C++ реализован механизм позднего связывания, когда разреше-
ние ссылок на метод происходит на этапе выполнения программы в зави-
симости от конкретного типа объекта, вызвавшего метод. Этот механизм 
реализован с помощью виртуальных методов. Для определения виртуаль-
ного метода используется спецификатор virtual. Правила описания и ис-
пользования виртуальных методов:
 Если в базовом классе метод определен как виртуальный, метод, опре-
деленный в производном классе с тем же именем и набором парамет-
ров, автоматически становится виртуальным, а с отличающимся набо-
ром параметров – обычным. 
 Виртуальные методы наследуются, т. е. переопределять их в производ-
ном классе требуется только при необходимости задать отличающиеся 
действия. Права доступа при переопределении изменить нельзя. 
 Если виртуальный метод переопределен в производном классе, объ-
екты этого класса могут получить доступ к методу базового класса
с помощью операции доступа к области видимости. 
 Виртуальный метод не может объявляться с модификатором static,
но может быть объявлен как дружественный.


Достарыңызбен бөлісу:
1   ...   18   19   20   21   22   23   24   25   ...   44




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет