Технологии программирования
Шрифт:
Если такую процедуру скомпилировать и поместить в динамическую библиотеку, то эту библиотеку можно будет раз и навсегда использовать без изменений, хотя будут появляться и новые, неизвестные в момент ее создания классы-потомки TField!
Наглядный пример использования полиморфизма дает сама Delphi. В ней имеется класс TComponent, на уровне которого сосредоточены определенные "правила" того, как взаимодействовать со средой разработки и с другими компонентами. Следуя этим правилам, можно порождать от TComponent свои компоненты, настраивая Delphi на решение специальных задач.
8. ОБРАБОТКА СООБЩЕНИЙ
Потребность в динамических
Методы, предназначенные специально дня обработки сообщений Windows, составляют подмножество динамических методов и объявляются директивой message, за которой следует индекс — идентификатор сообщения. Они должны быть обязательно описаны как процедуры, имеющие один var-параметр, который может быть описан произвольно, например:
Для перекрытия методов-обработчиков сообщений директива override не используется. В этом случае нужно сохранить в описании директиву message с индексом метода.
Необходимости изобретать собственные структуры, по-своему интерпретирующие содержание того или иного сообщения, нет: для большинства сообщений Windows типы уже описаны в модуле MESSAGES.
В обработчиках сообщений (и только в них) можно вызвать метод-предок, просто указав ключевое слово inherited, без указания его имени и преобразования типа параметров: предок будет найден по индексу. Следует напомнить, что система обработки сообщений встроена в Object Pascal на уровне модели объектов, и самый общий обработчик — метод DefaultHandler — описан в классе TObject.
9. СОБЫТИЯ И ДЕЛЕГИРОВАНИЕ
Работать с большим количеством сообщений, даже имея под рукой справочник, нелегко, поэтому одним из больших достижений Delphi является то, что программист избавлен от необходимости работать с сообщениями Windows (хотя такая возможность у него есть). Стандартных событий в Delphi не более двух десятков, и все они имеют простую интерпретацию, не требующую глубоких знаний среды.
Рассмотрим, как реализованы события на уровне языка Object Pascal. События — это свойства процедурного типа, предназначенные для создания пользовательской реакции на те или иные входные воздействия:
Присвоить такому свойству значение — это означает указать объекту адрес метода, который будет вызываться в момент наступления
Это означает, что при каждой активизации Application (так называется объект, соответствующий работающему приложению) будет вызван метод-обработчик MyActivatingMethod.
Внутри библиотеки времени выполнения Delphi вызовы обработчиков событий находятся в методах, обрабатывающих сообщения Windows. Выполнив принципиально необходимые действия, этот метод проверяет, известен ли адрес обработчика, и, если это так, вызывает его:
В зависимости от происхождения и предназначения события имеют разные типы. Общим для всех является параметр Sender, указывающий на объект-источник события. Самый простой тип — TNotifyEvent — не имеет других параметров:
Тип метода, предназначенный для извещения о нажатии клавиши, предусматривает передачу программисту кода этой клавиши, а передвижение мыши — ее координат и т. п.
Все события в Delphi принято именовать с "On": OnCreate, OnMouseMove, OnPaint и т. д. Щелкнув в Инспекторе объектов на странице Events в поле любого события, автоматически получается заготовка метода нужного типа. При этом его имя будет состоять из имени текущего компонента и имени события (без "On"), а относиться он будет к текущей форме. Пусть, например, на форме Form1 есть текст Label1. Тогда для обработки щелчка мышью на нем (событие OnClick) будет создан метод Tform1. Label1Click.
Поскольку события — это свойства объекта, их значения можно изменять во время выполнения программы. Такая замечательная возможность называется делегированием. Можно в любой момент взять способы реакции на события у одного объекта и делегировать их другому:
Но какой механизм позволяет подменять обработчики, ведь это не просто процедуры, а методы? Здесь как нельзя кстати приходится введенное в Object Pascal понятие указателя на метод. Помимо явно описанных параметров методу передается еще и указатель на вызвавший его экземпляр (Self). Вы можете описать тип процедуры, которая будет совместима по присваиванию с методом (т. е. предусматривать получение Self). Для этого в ее описание нужно добавить зарезервированные слова of Object. Указатель на метод — это указатель на такую процедуру: