Виртуальные и динамические методы

Классы

Классами в системе программирования Delphi называются специальные типы,

которые содержат составляющие класса: поля, методы и свойства. Составляющие класса

часто называют членами класса. Класс предназначен для создания конкретных экземпляров реализации, которые называются объектами.

Описание класса

Формат описания класса.

Type

<Имя класса> = Class

// члены класса

Поля

Свойства

Методы

End;

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

Инкапсуляция

Объединение в классе в одно целоеего членов называется инкапсуляцией.Инкапсуляция позволяет разграничить доступ к различным полям и свойствам класса. Некоторые поля и методы можно сделать свободно доступными в любом месте программы, другие поля и методы только внутри класса.

Наследование

Любой класс может быть порожден от другого класса. Тогда при объявлении такого класса после ключевого слова Class в круглых скобках указывается имя класса родителя.

TChildClass = Class(TParentClass)

 

End;

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

Все классы Delphi порождены от единственного родителя – класса TObject.

TaClass=Class(TObject);

Или

TaClass=Class;

Оба объявления равносильны.

Класс TObject. не имеет полей и свойств, но включает в себя множество методов самого общего назначения, обеспечивающие весь жизненный цикл любых объектов – от их создания до уничтожения.

Принцип наследования приводит к созданию ветвящегося дерева классов, постепенно разрастающегося при перемещении от класса TObject к его потомкам. Каждый потомок дополняет возможности своего родителя новыми возможностями и передает их своим потомкам.

Дочерний класс не может удалить какую-либо сущность родительского класса.

Полиморфизм

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

 

Составляющие класса

Поля.Полями называются инкапсулированные в классе данные. Поля могут быть любого типа, в том числе и классами. Например:

Type

TMyClass= class

aIntField: Integer;

aStrField: String;

aObjField: TObject;

End;

Каждый объект получает уникальный набор полей, но общий для всех объектов данного класса набор методов и свойств. Фундаментальный принцип инкапсуляции требует обращаться к полям только с помощью методов и свойств класса. Но в Delphi разрешается обращаться к полям напрямую. Доступ к полям возможен с помощью составных имен(как при доступе к полям записи):

Type

TMyClass= class

FIntField: Integer;

FStrField: String;

End;

В разделе описания переменных объявляется переменная этого класса, которая называется экземпляром класса или объектом.

Var

aObject: TMyClass;

Экземпляр класса является динамической переменной – указателем, содержащим адрес объекта.

Begin

//Составные имена – это имя переменной (точка)имя поля

aObject.FIntField:=0;

aObject.FStrField:=’Строка символов’;

End.

Класс потомок получает все поля своих предков и может дополнять их своими, но не может их переопределять или удалять. Таким образом, чем ниже в дереве иерархии располагается класс, тем больше данных получает в свое распоряжение его объекты.

Методы

Инкапсулированные в классе процедуры и функции называются методами.

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

 

Type

TMyClass= class

Function MyFunc(aPar:Integer):Integer;

Procedure MyProc;

End;

Var

aObject: TMyClass;

Begin

// Вызов метода через составное имя –это имя переменной(точка)имя метода

aObject.MyProc;

End.

Типы методов

В Delphi поддерживаются статические, виртуальные, динамические, перегружаемые и абстрактные методы.

Статические методы

Все методы по умолчанию считаются статическими

Type

TParentClass= Class

Procedure DoWork;

End;

TChildClass= Class(TParentClass)

Procedure DoWork;

End;

Var

Object_a: TParentClass;

Object_b: TGhildClass;

 

Потомки обоих классов могут выполнять сходную по названию процедуру DoWork, но

будут делать ее по-разному. Такое замещение методов называется статическим, так как реализуется компилятором.

Виртуальные и динамические методы

В Delphi чаще используется динамическое замещение методов на этапе прогона программы. Для реализации этого метода, замещаемый в родительском классе, должен объявляться как динамический (с директивой Dynamic) или виртуальный ( с директивой Virtual). В классе потомке замещаемый метод объявляется с директивой Override(перекрыть).

Перекрытие методов

Методы класса могут перекрываться в потомках.

Например, пусть родительский класс с помощью методов Show и Hide показывает изображение или прячет его на экране. Изображение создается методом Draw.

Type

TVisualObject=Class( TWinControl);

Procedure Show;

Procedure Hide;

Procedure draw(IsShow:Boolean); Virtual;//замещаемый

End;

TVisualChildObject=Class(TVisualOdject);

Prvirtual;ocedure draw(IsShow:Boolean); Override;//замещающий

End;

Реализация методов Show и Hide очень проста .

Procedure TVisualObject.Show;

Begin

Draw(True);

End;

Procedure TVisualObject.Hide;

Begin

Draw(False);

End;

Методы Draw у родителя и потомка имеют разную реализацию и создают разные изображения. В результате родительские методы Show и Hide будут прятать или показывать те или иные изображения в зависимости от конкретной реализации метода

Draw у любого из своих потомков. Динамическое связывание в полной мере реализует

полиморфизм классов.

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

Динамические перекрываемые методы часто могут ничего не делать. Такие методы называются абстрактными,они обязаны перекрываться в потомках. Можно запретить вызов абстрактного метода, объявив его с директивой Abstract. Например

Type

TVisualObject=Class( TWinControl);

procedure draw(IsShow:Boolean);virtual;abstract;

End;

TVisualChildObject=Class(TVisualOdject);

Procedure draw(IsShow:Boolean); Override;

End;

Var

aVisualObject: TVisualObject;

aVisualChildObject: TVisualChildObject;

begin

aVisualObject.Show; //Ошибка! Обращение к абстрактному методу

aVisualChildObject.Show; // Верное Обращение. Метод Draw у класса TVisualChildObject

// перекрыт

end;