Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Представление объекта, его внутренняя структура.




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

Type

TFirstClass = class

FMyFieldl: Integer;

FMyField2: Longint;

procedure StatMethod;

procedure VirtMethod1; virtual;

procedure VirtMethod2; virtual;

procedure DynaMethod1; dynamic;

procedure DynaMethod2; dynamic;

end;

TSecondClass = class(TFirstClass)

procedure StatMethod;

procedure VirtMethod1; override;

procedure DynaMethod1; override;

end;

Var

Objl: TFirstClass;

Obj2: TSecondClass;

 

Первое поле каждого экземпляра того или иного объекта содержит указатель на его класс.

Класс как структура состоит из двух частей:

1)Начиная с адреса, на который ссылается указатель на класс, располагается таблица виртуальных методов, которая содержит адреса всех виртуальных методов класса (VMT; включая унаследованные от предков). Длина таблиц VMT объектов Оbj1 и Obj2 одинакова – по два элемента (8 байт). Перед этой таблицей расположена спец. структура, содержащая дополнительную служебную информацию (полная  характеристика класса (имя, размер экземпляра, указатели на класс-предок и т. д.)

2)Одно из полей структуры содержит адрестаблицы динамических методов класса (DMT). Ее формат:

вначале слово, содержащее количество элементов таблицы, затем – слова, соответствующие индексам (с (-1)  по убывающей) методов, а после индексов идут собственно адреса динамических методов.

NB! В случае вызова Qbj2.DynaMethod2 индекс не будет найден в таблице DMT Obj2, и произойдет обращение к DMT Оbj1. Именно так экономится память при использовании динамических методов.

is и as

В языке OP определены два оператора — is и as, неявно обращающиеся к таблице динамических методов.

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

Выражениевида (AnObjectisTObjectType) принимает значение True, только если объект AnObjectявляется объектом этого класса или одного из классов, порожденных от него. Если формально объект и класс несовместимы, то компилятор выдаст ошибку в этом операторе (проверка на этапе компиляции).

As введен в язык специально для приведения объектных типов. С его помощью можно рассматривать экземпляр объекта как принадлежащий к другому совместимому типу:

with ASomeObject asTAnotherType do...

От стандартного способа приведения типов с помощью конструкции TAnotherType (ASomeObject) использование оператора as отличается наличием проверки на совместимость типов во время выполнения (как в операторе is): попытка приведения к несовместимому типу приводит к возникновению исключительной ситуации EInvalidCast.

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

Очень полезным может быть оператор as в методах-обработчиках событий. Для обеспечения совместимости в 99% случаев источник события Sender имеет тип TObject, хотя в тех же 99% случаев им является форма или другие компоненты. Поэтому, чтобы иметь возможность пользоваться их свойствами, применяют оператор аs: (SenderasTControl).Caption:= 'Спасибо!;

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

if Sender is TEdit                                                      {Определениеклассакомпонента}

then with (Sender as TEdit) do begin <…>end;

if ActiveControl is TEdit //Сравнениесклассомкомпонента

ifSender=MenuItemlthen... // Сравнениесименемкомпонента

else if Sender=MenuItem2 then ...

Области видимости

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

В модели объектов языка OP существует механизм доступа к составным частям объекта, определяющий области, где ими можно пользоваться (области видимости).

Методы и свойства могут быть:общими (секция public),личными (секция private),защищенными (секция protected), опубликованными (секция published).

Есть еще и пятая группа, automated, она ранее использовалась для создания объектов СОМ; теперь она присутствует в языке только для обратной совместимости с программами на Delphi версий 3-5.

Области видимости, определяемые первыми тремя директивами, таковы:

1)Поля, свойства и методы секции public не имеют ограничений на видимость.(Этот модуль и любой на него ссылающийся).

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

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

unitFirst;

interface

typeTFirstObj = class

Private

       procedure Method1;

Protected

       procedure Method2;

Public

       procedure Method3;

end;

unitSecond;

interface

uses First;

typeTSecondObj =class(TFirstObj)

       procedure Method4;

end;

procedure TestProc2;

Implementation

Var

       AFirstObj: TFirstObj;

       ASecondObj: TSecondObj;

procedure TSecondObj.Method4;

Begin

Method1; {недопустимо}

Method2; {допустимо}

Method3, {допустимо}

End;

procedure TestProc2;

Begin

AFirstObj:=TFirstObj.Create;

AFirstObj.Methodl; {недопустимо}

AFirstObj.Method2; {недопустимо}

AFirstObj.Method3; {допустимо}

AFirstObj.Free;

ASecondObj := TSecondObj.Create;

ASecondObj.Methodl; {недопустимо}

ASecondObj.Method2; {допустимо}

ASecondObj.Method3; {допустимо}

ASecondObj.Free;

end;

end.

4)Область published, имеет особое значение для интерфейса визуального проектирования Delphi. В этой секции должны быть собраны те свойства объекта, которые будут видны не только во время исполнения приложения, но и из среды разработки. Публиковать можно свойства большинства типов, за исключением старого типа real48и некоторых других. Все свойства компонентов, доступные через Инспектор объектов, являются их опубликованными свойствами. Во время выполнения такие свойства общедоступны, как и public.

Три области видимости — private, protected, public — как бы упорядочены по возрастанию видимости методов. В классах-потомках можно повысить видимость методов и свойств, но не понизить ее. При описании дочернего класса можно переносить методы и свойства из одной сферы видимости в другую, не переписывая их заново и даже не описывая — достаточно упомянуть о нем в другом месте:

Type

TFirstObj = class

Private

FNumber: Integer;

Protected

property Number: Integer read FNumber;

end;

...

TSecondObj = class(TFirstObj)

Published

property Number;

end;

Если какое-либо свойство объекта из состава VCL (объектно-ориентированные, назначением которых является удобный доступ к свойствам инструментов и прозрачная для пользователя обработка всех их изменений) принадлежит к области public, вернуть его в private невозможно. Напротив, обратная процедура широко практикуется в Delphi. У многих компонентов (например, TEdit) есть предок (в данном случае TCustomEdit), который отличается только отсутствием опубликованных свойств. Так что, если потребуется создать новый редактирующий компонент, необходимо породить его на базе TCustomEdit и опубликовать только те свойства, которые нужно. Если свойство помещено в область private, "достать" его оттуда в потомках возможности уже будет невозможно.

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

 










Последнее изменение этой страницы: 2018-04-11; просмотров: 185.

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