Objectl : TClassl; Object2 : TClass2; implementation — КиберПедия 

Состав сооружений: решетки и песколовки: Решетки – это первое устройство в схеме очистных сооружений. Они представляют...

История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...

Objectl : TClassl; Object2 : TClass2; implementation

2018-01-04 243
Objectl : TClassl; Object2 : TClass2; implementation 0.00 из 5.00 0 оценок
Заказать работу

// Реализация scex методов пример»

После выполнения создания экземпляров объектов: objectl :=TClassl.Create; Ob-iect2:»TClass2. Create;

внутренняя структура объектов эти: классов будет иметь вид, представленный ма рис. 3.6.

На рис. 3.6 наглядно видно, чем сличаются между собой различные методы при хранении в реальных объектах в оперативной памяти. Следует отметить, что в экземпляре объекта хранится адре«того места таблицы виртуальных методов, где хранится адрес первого виртуальяого метода. Служебная информация класса хранится по адресам оперативно! памяти с отрицательным смещением. Указанные смещения описаны в фай;е модуля System: vmtSelfPtr = -76;

vmtintfTable * -72;

vmtAutoTable = -68;

vmtlnitTable = -64;

vmtTypelnfo * -60;

vatFieldTable = -56;


 

 

vmtMethodTable = -52;

vmtDynamicTable = -48;

vmtClassName = -44;

vmtlnstanceSize = -40;

vmtParent = -36;

vmtSafeCallException = -32 deprecated;//don't use those constants.

vmtAfterConstruction = -28 deprecated;//use VMTOFFSET in asm instead

vmtBeforeDestruction = -24 deprecated;

vmtDispatch = -20 deprecated;

vmtDefaultHandler = -16 deprecated;

vmtNewInstance я -12 deprecated;

vmtFreelnstance = -8 deprecated;

vmtDestroy = -4 deprecated;

vmtQuerylnterface = 0 deprecated;

vmtAddRef = 4 deprecated;

vmtRelease = 8 deprecated;

vmtCreateObject = 12 deprecated;

Работать с этими областями оперативной памяти следует осторожно, поскольку информация в них используется Delphi для управления объектами и их экземплярами. При обращении к константам с директивой deprecated компилятор выдает предупреждение.

Правила выбора между виртуальными и динамическими методами. J. Если метод, скорее всего, будет перекрыт всеми потомками, его следует сделать виртуальным.

· Если метод будет перекрываться не очень часто, но все же требует позднего связывания для большей гибкости, то его следует сделать динамическим.

· Если метод будет вызываться очень часто, много раз в секунду, сделайте его виртуальным.

· Следует учитывать, что самые быстрые и экономичные - статические методы, которые, правда, не обеспечивают позднего связывания.

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

Иногда попытка создать иерархию классов путем выделения общих признаков приводит к тому, что образуется класс, методы которого реализовывать бессмысленно. Например, если создать класс ТAnimal, который должен объединять общие свойства всех животных, то в нем необходимо описать метод Voice (голос), поскольку большинство животных могут издавать звуки. Для каждого отдельного животного (объектов дочерних классов TAnimal) этот звук известен и можно, перекрыв метод Voice, определить его реализацию. Однако вызов метода Voice для объекта класса ТAnimal бессмыслен, и. следовательно, его реализация тоже. Тем не менее, формально, компилятор требует, чтобы любой метод, описанный в классе, был бы сеализован. Чтобы исключить создание подобного ненужного кода и были предусметрены абстоактные методы.

Абстрактный метод - это виртуальный или динамический метод, реализация которого не определена в том классе, з котором он объявлен. Предполагается, что этот метод должен быть объявлен в потомках. Объявляется такой метод с помощью ключевого слова abstract.

Пример 3.10. Описание абстрактного класса, type

TAnimal = class public

function Voice: string; virtual; abstract; end;

TDog = class (TAnimal) public

function Voice: string; override; function Eat: string; virtual; end;

TCat = class (TAnimal) public

function Voice: string; override; function Eat: string; virtual;

End; Implementation

Function TDog.Voice: string; begin

Result:= *Гав-гав'; and;

Function TDog.Eat: string; begin

Result:= 'Pedegree'; and;

Function TCat.Voice: string; begin

Result:= 'Мяу-мяу'; •nd;

function TDog.Eat: string;

Begin

Result 'Wiskas';

and;

Обратите внимание, что программисту не надо описывать реализацию

абстрактного метода TAnimal.Voice.

Object Pascal (в отличие от С++) позволяет создавать экземпляры объектов

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

My Animal: TAnimal; И создать экземпляр объекта MyAnimal: MyAnimal:= TAnimal.Create;

ro при вызове метода MyAnimal. Voice будет сгенерирована исключительная • и гуация (ошибка), поскольку была попытка вызвать абстрактный метод.

Рассмотрим использование абстрактных методов. Класс TAnimal содержит ииртуальный абстрактный метод Voice. Каждый наследник этого класса


 

 

перекрывает этот абстрактный метод, а также определяет новый метод Bat. Разница заключается в возможности применять полиморфизм. Например, пусть в тексте программы выполнено присваивание MyAnimal:= MyDog;

тогда становится возможным вызов MyAnimal. Voice, который реально выполнит код метода TDog. Voice. А вот вызов MyAnimal.Eat будет также невозможен, поскольку у объектов класса TAnimal не предусмотрен метод с таким названием, то есть для метода Eat полиморфизм не действует.

Информация о типах времени выполнения

Рассматривая приведенным выше пример, необходимо отметить, что все-таки существует возможность вызвать метод Eat, используя объект MyAnimal. Правда для этого используется уже не полиморфизм, а информация о типе времени выполнения (RTTI).

Механизм RTTI заключен в двух операциях для работы с объектами: is и as. Операция as фактически осуществляет приведение типа объекта к другому классу, например: MyAnimal as TDog. Данная конструкция возвращает указатель типа TDog на ту область оперативной памяти, где расположен экземпляр объекта MyAnimal. Таким образом, для объекта MyAnimal становится возможным вызов метода класса TDog: (MyAnimal as TDog).Eat

Однако если перед этим не было выполнено присваивание объекту MyAnimal объекта типа TDog, то при таком вызове произойдет ошибка времени выполнения. Чтобы избежать этой исключительной ситуации, можно использовать операцию is, которая возвращает true, если фактический тип объекта соответствует указанному в операции типу класса, иначе false.

if MyAnimal is TDog then

(MyAnimal as TDog).Eat;

Две операции RTTI, is и as, являются чрезвычайно мощными, и их можно рассматривать как стандартные конструкции программирования. Однако использование RTI "I вместо полиморфизма является плохим стилем программирования и приводит к более медленным программам, поскольку для проверки корректности преобразования типов приходится осуществлять обход по всей иерархии классов. Поэтому следует ограничивать их применение некоторыми специальными случаями, когда полиморфизмом не обойтись.

§3.9. Перегрузка методов

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

Перегружен может быть любой метод (статический, виртуальный и динамический). Перегружаемый метод описывается с помощью ключевого слова overload (не путать с override). Для виртуальных методов в этом случае нужно дополнительно использовать ключевое слово reintroduce.

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

TMyObject = class (TObject)

function Test (I: integer): string; overload; function Test (S: string): string; overload;

•nd;

Очевидно, что отличие двух методов состоит в типе передаваемого в метод параметра. Теперь если будет создан объект класса TMyObject, то при вызове метода Test будет вызван тот метод, к которому подойдет тип фактического

Параметра.

Пример перегрузки методов на разных уровнях иерархии: type

Tl = class (TObject)

procedure Te3t (X: Integer); overload;

end;

T2 = class (Tl)

procedure Test (S: String); overload;

end;

SomeObject:=T2.Create;

SomeObje-t.Test ('Hello!'); // вызывается T2.Test SomeObject. Test (7); // вызывается Tl.Test


Поделиться с друзьями:

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...

Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...

Эмиссия газов от очистных сооружений канализации: В последние годы внимание мирового сообщества сосредоточено на экологических проблемах...

Состав сооружений: решетки и песколовки: Решетки – это первое устройство в схеме очистных сооружений. Они представляют...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.017 с.