- •Объектно-ориентированное программирование
- •Часть 1 классы и объекты
- •Введение
- •1. Классы и объекты
- •Var aLine: tLine;
- •Var aColorLine: tColorLine;
- •2. Методы
- •2.1. Методы-функции и методы-процедуры
- •2.2. Конструкторы и деструкторы
- •Inherited Create;
- •Var TmpFrm: tForm;
- •Var Mem: tMemo;
- •2.3. Классовые процедуры и функции
- •Var s: String;
- •2.4. Скрытый Self
- •3. Видимость компонентов класса
- •4. Наследование
- •4.1. Основные понятия
- •4.2. Наследование полей
- •4.3. Поведение методов при наследовании
- •Var SomeObject: t1;
- •Virtual;
- •Virtual; Abstract;
- •4.4. Иерархия классов
- •4.5. Rtti
- •4.6. Проверка типа
- •4.7. Приведение типа
- •4.8. Указатели на класс
- •Var ObjRef: tObjRef;
- •Implementation
- •X, y, w, h: Integer): tControl;
- •5. Полиморфизм
- •6. Свойства (properties)
- •6.1. Объявление свойств
- •6.2. Объявления свойств-массивов
- •Var I: Byte;
- •6.3. Раздел Read
- •6.4. Раздел Write
- •Inherited Create;
- •Inherited Destroy;
- •6.5. Команды Default, NoDefault и Stored
- •6.6. Команда Index
- •Var aYear, aMonth, aDay: Word;
- •Var aYear, aMonth, aDay: Word;
- •6.7. Команды DispId и Implements
- •6.8. Переопределение свойств при наследовании
- •7. События (events)
- •7.1. Объявление событий
- •IfAssigned(fOnMouseMove) Then fOnMouseMove(Self, Shift, X, y);
- •Vk_return: NumMemo.DoNumStr(l);
- •Vk_return: PostMessage(NumMemo.Handle, wm_user1,1, 0);
- •7.2. Обработчики событий
- •7.3. Делегирование событий
- •Var Objl: tIstClass;
- •7.4. Переопределение стандартных событий
- •Var NewBtn: tNewButton;
Var SomeObject: t1;
Begin
SomeObject:=T2.Create;
SomeObject.Test; // Вызывается T1.Test
• У каждого производного класса свое пространство имен, предваряющее пространство имен всех наследуемых этим классом методов. Поэтому можно скрыть наследуемый метод, объявив одноименный виртуальный метод. Однако в VMT таблице сохраняется адрес нового и старого (переопределенного) виртуального метода, следовательно, к переопределенному виртуальному методу возможен доступ с использованием механизма приведения типов:
TParentClass(Obj). <метод>;
Синтаксис объявления виртуальных методов:
Procedure|Constructor|Destructor <имя метода>[(<параметры>)};
Virtual;
Function <имя метода>[(<параметры>)]: <тип результатам>; Virtual;
в) Динамические методы.
Динамические методы вызываются медленнее виртуальных, но позволяют более экономно расходовать память. Каждому динамическому методу присваивается индекс - отрицательное число. В таблице динамических методов (Dynamic Method Table, DMT) класса хранятся индексы и адреса только тех динамических методов, которые описаны в данном классе. Если в DMT данного класса адрес нужного динамического метода не находится, то просматривается DMT класса-предка, и так далее по всей цепочке наследования до класса TObject. Таким образом, доступ к методу через DMT может привести к активному поиску в DMT разных классов и потребовать сотен тактов процессора.
Во всем остальном между виртуальными и динамическими методами нет принципиальной разницы. Там, где можно использовать виртуальный метод, там можно использовать и динамический, но с меньшими затратами памяти и быстродействием. Динамические методы используются для редко вызываемых методов, когда потерями в производительности можно пренебречь. Синтаксис объявления динамических методов:
Proctdure <имя метода>[(<параметры>)}; Dynamic;
Function <имя метода>[(<параметры>)}: <тип результата>;Т>упят.1С;
Редко перекрываемые методы рекомендуется делать динамическими.
г) Замещающие методы.
В то время как, директивы Virtual и Dynamic всегда вводят новое имя метода, то директива Override всегда указывает на новую реализацию уже существующего наследуемого виртуального или динамического метода. Весь смысл виртуальных и динамических методов состоит в том, чтобы дать классу-потомку возможность модифицировать поведение метода, введенного в его классе-предшественнике. Директива Override служит для того, чтобы дать понять транслятору, что ваша цель - модифицировать (заменить или расширить - два разных варианта) реализацию наследуемого метода.
Объявление Override-метода должно в точности совпадать с объявлением исходного Virtual или Dynamic метода по названию, числу, именам и типам параметров, а также типу результата для функции. Новая строка в VMT (DMT) таблице не создается, поскольку адрес замещенного метода записывается в строку таблицы замещаемого метода. Таки" образом, у класса-предка и класса-потомка адрес одноименного метода находится в строке таблицы VMT (DMT) с одинаковым смещением от ее начала. Однако "начинка" этих методов различна.
Синтаксис объявления замещающих виртуальных методов:
Procedure|Constructor|Destructor <имя метода>[(<параметры>)];Override;
Function <имя метода>[{<параметры>)]: <тип результата>; Override;;
Если в одноименных статических методах производных классов списки параметров могут различаться, то список параметров виртуального метода нельзя изменять при замещении в производном классе. Это объясняется тем, что нет никакой связи между одноименными статическими методами производных классов, и есть сильная связь между одноименными виртуальными методами. Так вызов виртуального метода может во время работы программы привести к вызову любой из его реализации (принцип полиморфизма) в производных классах, поэтому у них у всех должны быть идентичные списки параметров.
д) Абстрактные методы.
Абстрактными называются методы, которые определены в классе, но не содержат его реализации в этом классе. Они никогда не вызываются в объявленном классе и должны быть переопределены и реализованы в его наслед никах. Абстрактными могут быть только виртуальные и динамические методы. Их основное назначение, - абстрагируясь от частностей, быть родоначальниками иерархии конкретных методов в классах наследниках. Такие методы лежат в основе принципа полиморфизма. Для объявления метода абстрактным используется слово-директива Abstract, которое указывается после слова-директивы Virtual (Dynamic). Эта директива действительна лишь при первом объявлении метода класса. Если абстрактный метод в наследниках оказался неопределенным, то его вызов генерирует ошибку или исключительную ситуацию.
Синтаксис объявления абстрактных методов:
Procedure <имя метода>[(<параметры>)]; Virtual; Abstract;
Function <имя метода>[(<параметры>)]: <тип результата>;
