- •1. Новые концепции ооп в языке Oblect Pascal
- •2. Объектно-ориентированный подход в программировании
- •Основные понятия
- •3. Понятие класса и объекта
- •4. Поля, методы и свойства объекта
- •5. Ключевое слово Self, примеры использования
- •6. Перегруженные методы
- •7. Создание и удаление объектов
- •8. Инкапсуляция
- •9. Инкапсуляция и модули
- •10. Директивы видимости
- •11. Инкапсуляция при помощи свойств
- •12. Свойства-массивы
- •13. Индексированные свойства
- •14. Свойства и иерархия классов
- •15. Конструкторы, перегрузка конструкторов, 16. Деструкторы
- •17. Ссылочная модель объектов Delphi
- •18. Наследование
- •19. Совместимость типов
- •20. Полиморфизм и позднее связывание
- •21. Виртуальные, динамические методы
- •22. Абстрактные методы
- •23. Бе6зопасное преобразование типов
- •24. Ссылки на класс
- •25. Создание компонентов при помощи ссылок на класс
- •26. Интерфейсы
- •27. Технические приемы, связанные с использованием интерфейсов (делегирование, использование директивы implements)
- •28. Исключительные ситуации
- •29. Порядок выполнения программы и блок finally
- •30. Классы исключений
- •31. Исключения и отладка приложений
- •32. Класс tObject, использование методов класса Tobject
- •33. Понятие события
- •34. Обработчики событий. Делегирование в Delphi
- •35. События стандартных визуальных компонент и их использование
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. Обратное – плохой стиль программирования и снижает производительность программы, так как для проверки корректности классов необходимо проходить по всей иерархии классов, а для обращения к виртуальному методу требуется просто прочитать его адрес из памяти.
