![]() Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Наследование
Наследование – это принцип ООП, посредством которого на базе существующих классов создаются новые классы, получающие по наследству от базовых классов свойства и методы. Наследование позволяет существенно экономить программный код. Созданные с использованием механизма наследования новые классы называются классами-наследниками или классами-потомками. //Объявление базового класса class A { … //Члены класса A }; //Объявление класса-наследника class B: public A { … //Собственные члены класса B }; Новые классы наследуют только те свойства и методы, которые объявлены в разделах public и protected базовых классов. При этом свойства и методы из раздела protected доступны только базовому классу и его наследникам, тогда как свойства и методы из раздела public доступны объектам любого класса (рис. 17.1). Исключением из этого правила являются конструкторы и деструкторы, которые не наследуются. Рис. 17.1. Уровни доступа к членам класса В состав класса B входят собственные члены и члены класса A из разделов public и protected. Рассмотрим пример наследования, в качестве базового класса возьмем класс person, характеризующий любого человека, и включим в раздел protected свойство класса name – имя человека: class person { protected: char name[20]; }; Создадим на основе класса person класс-наследник student: class student: public person { char department[20]; // факультет public: student(char* _name, char* _department); void message(); }; //Конструктор student:: student(char* _name, char* _department) { strcpy(name, _name); strcpy(department, _department); } //message – метод, сообщающий сведения об объекте void student:: message() { cout < < " My name is " < < name < < ". I study at " < < department < < endl; } Как видно, методы класса student используют как собственное свойство, так и свойство, полученное по наследству. Создание объекта класса student и вызов его метода ничем не отличаются от того, как это делается для класса без наследования: int main(void) { student N(" Nick", " SS, SK, VT"); N.message(); return 0; } Во время выполнения такой программы на экране появляется сообщение: My name is Nick. I study at SS, SK, VT. Теперь рассмотрим наследование методов базового класса, включим в базовый класс конструктор, инициализирующий собственное свойство базового класса значением " Noname", и метод message, сообщающий информацию о классе: class person { protected: char name[20]; public: person(); void message(); }; person:: person() { strcpy(name, " Noname"); } void person:: message() { cout < < " My name is " < < name < < endl; } Таким образом, в класс-наследник student теперь включены два метода message, имеющие одинаковый тип и одинаковый список параметров – один из базового класса, другой – собственный. Собственный метод доступен через имя объекта. Однако можно получить доступ к унаследованному методу, если использовать для доступа к методу указатель соответствующего типа – указатель на базовый класс: int main(void) { person A; student B(" Ann", " SS, SK, VT");
A.message(); B.message(); person* pperson = & B; pperson-> message(); student* pstudent = & B; pstudent-> message(); return 0; } На экране увидим сообщения: Noname Сообщение об= объекте A Ann SS, SK, VT Сообщение об объекте B (используется собственный метод message) Ann Сообщение об объекте B (используется метод message, полученный по наследству) Ann SS, SK, VT Сообщение об объекте B (используется собственный метод message) В С++ можно избежать получения по наследству метода, если метод с таким же именем включен в класс-потомок, для этого используется механизм виртуальных функций. Виртуальная функция - это функция, объявленная в базовом классе с помощью ключевого слова virtual, такая функция в классах-потомках замещается на функцию, принадлежащую производному классу и имеющую то же имя: class person { protected: char name[20]; public: person(); virtual void message(); }; Теперь результатом выполнения программы будут следующие сообщения: Noname Сообщение об объекте A Ann SS, SK, VT Сообщение об объекте B (используется собственный метод message) Ann SS, SK, VT Сообщение об объекте B (используется собственный метод message) Ann SS, SK, VT Сообщение об объекте B (используется собственный метод message) С помощью виртуальных функций можно создать класс-наследник, имеющий тот же интерфейс, что и базовый класс, но обладающий своей собственной моделью поведения. Механизм виртуальных функций реализуется следующим образом: обычно обработка вызовов функций выполняется на этапе компиляции и завершается на этапе редактирования связей, когда вызов метода жестко связывается с соответствующей функцией (раннее связывание); если метод объявлен как виртуальный, выполняется так называемое позднее связывание, т. е. связывание вызова и функции во время выполнения программы.
|