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

22. Абстрактные методы

Ключевое слово abstract используется для объявления методов, которые будут определены только в наследниках тех классов, т.е. указывают на то, что класс содержит только объявление метода, но не содержит определения. Директива abstract полностью определяет метод, т.е. при попытке добавить в код реализацию этого метода, компилятор выдаст ошибку. OP позволяет сделать экземпляр класса, содержащего абстрактные методы, однако при этом будет выдано соответствующее предупреждение. Благодаря использованию абстрактных методов упрощается реализация полиморфизма. Например, если класс TAnimal имеет абстрактный метод Voice, то каждый потомок класса может использовать общий объект класса TAnimal, и при этом можно обратиться к методу Voice объекта MyAnimal, вне зависимости от того, к какому подклассу он фактически принадлежит этот объект. Если бы в классе TAnimal не было абстрактного метода Voice, вызов было бы осуществить невозможно.

23. Бе6зопасное преобразование типов

Правила OP о совместимости типов позволяют использовать класс потомка там, где ожидается использование класса предка. Пример. TAnimal = class private kind: string; public constructor Create(k : string); function Say: string; virtual; abstract; end; TDog = class(TAnimal) public function Say: string; override; function Eat: string; end; TCat = class(TAnimal) public function Say: string; override; function Eat: string; end; В нашем примере в основном коде программы мы везде писали класс TAnimal, т.е. ожидается его использование, но используем его потомков. Если мы попытаемся вызвать метод Eat, то можем использовать механизм прямого преобразования типов. Но, если оказывается, что переменная указывает на объект другого класса, возникает ошибка времени выполнения: TDog(MyAnimal).Eat – т.к. компилятор не может определить, является тип корректным. Остается использовать механизм RTTI. Каждый объект знает свой тип и тип своего родителя. К этой информации можно обратиться, используя операцию is или метод InheritsFrom. Параметрами операции is является тип класса, а взовращаемое значение – boolean. Т.е. выражение истинно, если объект MyAnimal ссылается в данный момент на объект класса TDog или его потомка. После того, как мы уверены, что наша пременная совместима с классом TDog, то в дальнейшем можем использовать прямое преобразование типов. Все эти действия выполняются в комплексе с другой операцией RTTI, которая обозначается as. Эта операция преобразовывает объект только в том случае, если тип запрашиваемого класса совместим с текущим. Параметрами операции as является объект и тип класса, а результатом является объект, приведенный к этому типу. MyDog:= MyAnimal as TDog; Text:= MyDog.Eat; или, например, (MyAnimal as TDog).Eat. Операция as вызывает исключительную ситуацию, если тип объекта не совместим с типом класса, к которому мы собираемся его привести. Чтобы избежать возникновения этой ситуации, нужно использовать операцию is, и, если она даёт результат true, можно выполнить прямое преобразование типов. (Нет необходимости использовать as и is последовательно, дважды выполняя проверку). Операции is и as – чрезвычайно мощные, однако их применение следует ограничить несколькими специальными случаями. При необходимости решить сложную задачу, связанную с несколькими классами, надо попытаться использовать полиморфизм, и только потом, если необходимо, дополнить его операциями RTTI. Обратное – плохой стиль программирования и снижает производительность программы, так как для проверки корректности классов необходимо проходить по всей иерархии классов, а для обращения к виртуальному методу требуется просто прочитать его адрес из памяти.

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