Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP_Otvety.docx
Скачиваний:
13
Добавлен:
07.04.2025
Размер:
2.59 Mб
Скачать

6. Полиморфизм: переопределение и перекрытие методов. Вызов унаследованных методов. Варианты реализации в разных языках. Виртуальный деструктор.

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

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

Переопределение метода – повторное определение метода, который есть в предке, в потомке. Перекрытие метода – переопределение виртуального метода.

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

class Animal{ virtual void sound(){printf(“!!”);} }; class Cat : public Animal{ void sound(){printf(“Mew”);} }; class Dog : public Animal{ void sound(){printf(“Wow”);} }; Animal a = new Cat; Animal a1 = new Dog; a->sound() //mew a1->sound() //wow

Наследование как возможность воспользоваться уже готовым классом, но дополнить и расширить его, и все вытекающие отсюда способы заменить и расширить существующую функциональность – например, вызов унаследованных методов предка;

Для невиртуальных методов адрес вызова одинаков и известен заранее на момент компиляции (раннее связывание). Для виртуального метода адрес реального вызова на момент компиляции неизвестен и берется из таблицы в момент вызова метода (позднее связывание).

Виртуальными должны быть все деструкторы. Заметьте, кстати, что в случае виртуального деструктора вызывается не только он, но и все деструкторы предков в обратном порядке, как положено. Итак, общее правило: виртуальный деструктор в базовом классе обязательно нужен тогда, когда вы создаёте объекты классов-потомков и храните их в переменных классов-предков. В этом случае при удалении объекта-потомка, лежащего в переменной класса-предка, вызовется полная корректная последовательность деструкторов, а не только деструктор класса-предка.

Абстрактный класс – класс у которого хоть один метод абстрактный. В С++ virtual void foo() = NULL;

Объекты абстрактного класса создавать нельзя. Потомки должна переопределять все абстрактные методы, иначе они тоже абстрактные.

7. Приведение типов. Правила, цель, стандартные приемы. Самостоятельная реализация, варианты реализации в разных языках.

Приведение типа — преобразование значения одного типа в значение другого типа.

Выделяют приведения явные и неявные. Явное приведение задается программистом в коде, например, при помощи специальных конструкций языка. Неявное приведение выполняется компилятором при, например, вычислении арифметических выражений.

Явное приведение может быть безопасным (с проверкой) или небезопасным (без проверки). Пример небезопасного:

Animal a = new Cat();

((Cat) a).chase();

Для безопасного приведения типов можно использовать механизмы используемого языка или ручную проверку типов:

● с помощью виртуального метода getClassName(), недостаток которого состоит в том, что он не учитывает иерархию классов; if (a->getClassName() == “Cat”) ((Cat*)a)->catch();

● с помощью виртуального метода isA(String _who), который этого недостатка лишен. bool isA(string who){ return (who == getClassName() || Base::isA(who)); //Base - имя класса ближайшего предка

В C++ можно использовать, например, dynamic_cast:

Cat* c = dynamic_cast<Cat *>(a); if (c!= NULL) c->catch();

Если приведение успешно, то вернется указатель нужного типа, иначе NULL.

Цель приведение типов — например, использование специфических методов дочерних классов при хранении объектов в хранилище родительского типа.

Соседние файлы в предмете Объектно ориентированное программирование