Помощничек
Главная | Обратная связь


Археология
Архитектура
Астрономия
Аудит
Биология
Ботаника
Бухгалтерский учёт
Войное дело
Генетика
География
Геология
Дизайн
Искусство
История
Кино
Кулинария
Культура
Литература
Математика
Медицина
Металлургия
Мифология
Музыка
Психология
Религия
Спорт
Строительство
Техника
Транспорт
Туризм
Усадьба
Физика
Фотография
Химия
Экология
Электричество
Электроника
Энергетика

Программирование на Delphi


 

Этот курс посвящен среде разработки Delphi фирмы Borland- которая на протяжении многих лет успешно выдерживает жесткую конкуренцию с другими средами программирования.Концепция Delphi1 была реализована в конце 1994 года, когда вышла перваяверсия среды разработки. В основу этого программного продукта легликонцепции объектно-ориентированного программирования (ООП) на базе языкаObject Pascal и визуального подхода к построению приложений.После выхода Delphi 1 все компьютерные издания писали об этой среде, как об“убийце Visual Basic”. Появление Delphi 2 (32-разрядной) ознаменовало новуюэпоху, - появился доступ к возможностям программных интерфейсов Windows NTи Windows 95, протоколам OLE. Delphi 2 стала средством разработкиполноценных приложений клиент/сервер. Вскоре Delphi 3 предоставиларазработчикам средства создания распределенных многоуровневых приложений иполноценный инструментарий проектирования приложений для Internet иintranet. Появилась полноценная поддержка COM - модели объектов, ставшейкраеугольным камнем современного программирования. Четвертая версия Delphiпозволяет полностью интегрировать ваши разработки с объектами COM.Поддержка архитектуры CORBA (Common Object Request Broker Architecture)открывает перед приложениями, созданными в Delphi для платформы Wintel(Windows + Intel), мир других операционных систем (UNIX, OS/2, WMS).Общаться с крупными корпоративными СУБД стало также просто, как и со старымдобрым Paradox. Вы можете использовать в своей работе любые уровнимежзадачного взаимодействия: от простейшего на уровне сокетов, до связи стакими перспективными инструментами, как Microsoft Transaction Server.
Delphi представляет следующие новые свойства и усовершенствования: . Новые расширения языка. В Delphi в язык Object Pascal включены динамические массивы, методы обработки переполнения, установка значения параметров по умолчанию, и многое другое. . Менеджер Проекта Новый менеджер проекта позволяет Вам объединять проекты которые работают вместе в одину проектную группу. Это позволяет Вам организовать как работу взаимозависимых проектов, таких как однозадачные и многозадачные приложения или DLL, так и совместную работу исполняемых программ. . Новый проводник Новый проводник содержит выполняемые классы, навигацию по модулям, и браузер кода. Проводник кода делает создание классов проще, автоматизирую многие из шагов. Введите прототип метода в разделе интерфейса и свойство выполняемого класса сгенерирует скелетный код в разделе реализации. Также проводник позволяет быстро перемещаться через файлы модуля, а так же между интерфейсом и реализацией. Использование символа Tooltip, позволяет просматривать информацию об объявлении любого идентификатора, затем используя борузер код, можно перейти к его объявлению. . Закрепляемые окна инструментов. IDE (Интегрированная Среда азработки) содержит более перенастраеваемую конфигурацию окон инструментов, которые можно закреплять с редактором кода. Просто перетащите и отпустите окно инструмента к тому месту, к которому хотите. Проводник кода и менеджер проекта можно как закреплять, так и незакреплять. . Улучшенная отладка. Интегрированный отладчик имеет много новых свойств, включая удаленную и многопроцессорную отладку, просмотр кода центрального процессора, инспекторов, усовершенствованные точки прерывания, отладчик специфических подменю и закрепленных окон. . Поддержка MTS. Явная поддержка для использования MTS интегрирована в поддержку многоуровневых баз данных. Кроме того, новый мастер облегчит Вам создание объектов сервера MTS. . Усовершенствования ActiveX. . Delphi обеспечивает расширенную поддержку ActiveX. . Усовершенствования VCL. Иерархия объектов Delphi быда расширена, чтобы включить новый компонент для NT Service приложений. Кроме того, новый компонент выполняемого списка (на Стандартной странице палитры), позволяет Вам централизовать управление меню и команд от кнопок. Управление VCL расширено, чтобы поддерживають drag-and-drop перетаскивания, обеспечивать дополнительный контроль над размещением окна, и многое другое. . Поддержка RTL для 2000-го года. . Глобальная переменная TwoDigitYearCenturWwindow используется функциями StrtToDate и StrToTateTime, чтобы управлять интерпретацией лет с двумя цифрами при преобразовании дат. . Поддержка CORBA. Версии Клинт/Сервер и предприятие включают поддержку для CORBA клиент и сервер приложений. Мастера помогут Вам легко создать сервер CORBA и Динамический Интерфейс Вызова (DII), позволяя Вам записывать клиентов для существующих серверов CORBA. CORBA имеет возможность поддержки в много-уровневых баз данных. Вы можете даже создать сервер, который обрабатывает COM клиентов и CORBA клиентов одновременно.


Delphi - это комбинация нескольких важнейших технологий: . Высокопроизводительный компилятор в машинный код . Объектно-ориентированная модель компонент . Визуальное (а, следовательно, и скоростное) построение приложений из программных прототипов . Масштабируемые средства для построения баз данныхКомпилятор, встроенный в Delphi, обеспечивает высокую производительность,необходимую для построения приложений в архитектуре “клиент-сервер”. Онпредлагает легкость разработки и быстрое время проверки готовогопрограммного блока, характерного для языков четвертого поколения (4GL) и вто же время обеспечивает качество кода, характерного для компилятора 3GL.Кроме того, Delphi обеспечивает быструю разработку без необходимости писатьвставки на Си или ручного написания кода (хотя это возможно).В процессе построения приложения разработчик выбирает из палитры компонентготовые компоненты как художник, делающий крупные мазки кистью. Еще докомпиляции он видит результаты своей работы - после подключения к источникуданных их можно видеть отображенными на форме, можно перемещаться поданным, представлять их в том или ином виде. В этом смысле проектирование вDelphi мало чем отличается от проектирования в интерпретирующей среде,однако после выполнения компиляции мы получаем код, который исполняется в10-20 раз быстрее, чем то же самое, сделанное при помощи интерпретатора.Кроме того, компилятор компилятору рознь, в Delphi компиляция производитсянепосредственно в родной машинный код, в то время как существуюткомпиляторы, превращающие программу в так называемый p-код, который затеминтерпретируется виртуальной p-машиной. Это не может не сказаться нафактическом быстродействии готового приложения.Объектно-ориентированная модель программных компонент. Основной упор этоймодели в Delphi делается на максимальном реиспользовании кода. Этопозволяет разработчикам строить приложения весьма быстро из заранееподготовленных объектов, а также дает им возможность создавать своисобственные объекты для среды Delphi. Никаких ограничений по типамобъектов, которые могут создавать разработчики, не существует.Действительно, все в Delphi написано на нем же, поэтому разработчики имеютдоступ к тем же объектам и инструментам, которые использовались длясоздания среды разработки. В результате нет никакой разницы междуобъектами, поставляемыми Borland или третьими фирмами, и объектами, которыевы можете создать.В стандартную поставку Delphi входят основные объекты, которые образуютудачно подобранную иерархию базовых классов. Но если возникнетнеобходимость в решении какой-то специфической проблемы на Delphi,советуем, прежде чем попытаться начинать решать проблему “с нуля”,просмотреть список свободно распространяемых или коммерческих компонент,разработанных третьими фирмами, количество этих компонент в настоящее времясоставляет несколько тысяч. Событийная модель в Windows всегда была сложнадля понимания и отладки. Но именно разработка интерфейса в Delphi являетсясамой простой задачей для программиста.Объекты БД в Delphi основаны на SQL и включают в себя полную мощь BorlandDatabase Engine. В состав Delphi также включен Borland SQL Link, поэтомудоступ к СУБД Oracle, Sybase, Informix и InterBase происходит с высокойэффективностью. Кроме того, Delphi включает в себя локальный серверInterbase для того, чтобы можно было разработать расширяемые на любыевнешние SQL-сервера приложения в офлайновом режиме. азработчик в средеDelphi, проектирующий информационную систему для локальной машины (кпримеру, небольшую систему учета медицинских карточек для одногокомпьютера), может использовать для хранения информации файлы формата .dbf(как в dBase или Clipper) или .db (Paradox). Если же он будет использоватьлокальный InterBase for Windows (это локальный SQL-сервер, входящий впоставку), то его приложение безо всяких изменений будет работать и всоставе большой системы с архитектурой клиент-сервер. Вот она -масштабируемость на практике - одно и то же приложение можно использоватькак для локального, так и для более серьезного клиент-серверного вариантов.

 

1. Основы объектно-ориентированного программированияПонятие класса.Классом в Delphi называется особый тип, который может иметь в своем составеполя, методы и свойства. Такой тип также называют объектным типом. typetMyClass=ass(tObject)fMyFiled: integer;function MyMethod: integer;end; Поля класса аналогичны полям записи. Это - данные, уникальные в программедля каждого созданного в программе экземпляра класса. Описанный выше классtMyClass имеет одно поле - fMyFiled. В отличие от полей, методы у двухэкземпляров одного класса общие. Методы - это процедуры и функции,описанные внутри класса, и предназначенные для операций над его полями. Всостав класса входит указатель на специальную таблицу - таблицу виртуальныхметодов (VMT), в которой содержится вся информация, необходимая для вызоваметодов. От обычных процедур и функций методы отличаются тем, что привызове в них передается указатель на экземпляр класса, который их вызвал.Поэтому обрабатываться будут поля именно того объекта, который вызвалметод. Внутри методов указатель на вызвавший их объект доступен череззарезервированное слово Self. Свойством класса называется совокупность поляи методов чтения/записи, обеспечивающих доступ к этому полю. При этом самополе декларируется как private (доступно только внутри данного класса), идоступ к нему возможен только посредством соответствующих методов.Подробнее свойства будут обсуждаться ниже.Понятие объектаЧтобы использовать новый тип в программе, нужно, как минимум, определитьпеременную этого типа. Переменная объектного типа называется экземпляромтипа или объектом: var aMyObject: tMyClass; До введения понятия “класс” в языке Pascal существовала двусмысленностьопределения “объект”, который мог обозначать и тип, и переменную этоготипа. Теперь существует четкая граница: класс - это описание, объект - то,что создано в соответствии с этим описанием.Создание и уничтожение объектовВ отличие от С++ и Turbo Pascal в Delphi объекты могут быть толькодинамическими!!!. Это означает, что в приведенном выше примере переменнаяaMyObject на самом деле является указателем, содержащем адрес объекта.Объект создается конструктором и уничтожается деструктором. aMyObject :=MyClass.Create; // // действия с созданным объектом // aMyObject.Destroy;Следует обратить внимание на то, что для создания объекта aMyObjectвызывается метод класса tMyClass.Create. Конструктор класса (и ряд другихметодов) успешно работает и до создания объекта. Однако большинство обычныхметодов (в частности все виртуальные и динамические методы). Вызывать доинициализации объекта не следует.
В Delphi конструкторов у класса может быть несколько. Общепринято называтьконструктор Create, в отличие от Turbo Pascal, где конструкторы называлисьInit, и С++, в котором имя конструктора совпадает с именем класса. Типичноеназвание деструктора - Destroy. typetMyClass=ass(tObject)fMyFiled: integer;Constructor Create;Destructor Destroy;function MyMethod: integer;end; Для уничтожения объекта в Delphi рекомендуется использовать не деструктор,а метод Free, который первоначально проверяет указатель, и только затемвызывает деструктор Destroy: procedure tObject.Free; До передачи управления телу конструктора происходит собственно созданиеобъекта: под него отводится память, значения всех полей обнуляются. Далеевыполняется код конструктора, написанный программистом для инициализацииобъектов данного класса. Таким образом, несмотря на то, что синтаксисконструктора схож с вызовом процедуры (отсутствует возвращаемое значение),на самом деле конструктор - это функция, возвращающая созданный ипроинициализированный объект.Примечание. Конструктор создает новый объект только в том случае, еслиперед его именем указано имя класса. Если указать имя уже существующегообъекта, он поведет себя по-другому: не создаст новый объект, а тольковыполнит код, содержащийся в теле конструктора.Чтобы правильно проинициализировать в создаваемом объекте поля, относящиесяк классу - предку, нужно сразу же при входе в конструктор вызватьконструктор предка при помощи зарезервированного слова inherited: constructor tMyClass.Create;Begininherited Create;// Код инициализации tMyClassEnd; Как правило, в коде программ, написанных на Delphi, практически нвстречается вызовов конструкторов и деструкторов. Дело в том, что любойкомпонент, попавший при визуальном проектировании в приложение из палитрыкомпонентов, включается в определенную иерархию. Эта иерархия замыкается наформе (класс tForm): для всех ее составных частей конструкторы идеструкторы вызываются автоматически, незримо для программиста. Кто создаети уничтожает формы? Это делает приложение (объект с именем Application). Вфайле проекта (с расширением DPR) вы можете увидеть вызовы методаApplication.CreateForm, предназначенного для этой цели.Что касается объектов, создаваемых динамически (во время выполненияпрограммы), то здесь нужен явный вызов конструктора и метода Free.

 


Свойства:Как известно, существует три основных принципа, составляющих суть объектно-ориентированного программирования: инкапсуляция, наследование иполиморфизм. Классическое правило объектно-ориентированногопрограммирования утверждает, что для обеспечения надежности нежелателенпрямой доступ к полям объекта: чтение и изменение их содержимого должноосуществляться посредством вызова соответствующих методов. Это правилоназывается инкапсуляцией (сокрытие данных). В старых реализациях ООП(например в Turbo Pascal) эта мысль внедрялась только посредством призывови примеров в документации; в Delphi есть соответствующая конструкция.Пользователь объекта в Delphi может быть полностью отгорожен от полейобъекта при помощи свойств.Обычно свойство определяется тремя элементами: полем и двумя методамиосуществляющими его чтение/запись: typetMyClass=ass(tObject)function GetaProperty: tSomeType;procedure SetaProperty(Value: tSomeType);property aProperty: tSomeType read GetaPropertywrite SetaProperty;end; В данном примере доступ к значению свойства aProperty осуществляется черезвызовы методов GetaProperty и SetaProperty, однако в обращении к этимметодам в явном виде нет необходимости: достаточно написать aMyObject.aProperty:=alue; aVarable:=MyObject.aProperty; и Delphi откомпилирует эти операторы в вызовы соответствующих методов. Тоесть внешне свойство выглядит в точности как обычное поле, но за всякимобращением к нему могут стоять вызовы необходимых программисту методов.Например, если есть объект, представляющий собой квадрат на экране, и егосвойству “цвет” присваивается значение “белый”, то произойдет немедленнаяпрорисовка, приводящая реальный цвет на экране в соответствие значениюсвойства.В методах, устанавливающих значения свойства, может производиться проверказначения на попадание в заданный диапазон значений и вызов других процедурзависящих от вносимых изменений. Если же потребности в специальныхпроцедурах чтения/записи нет, можно вместо имен методов применять именаполей. tPropClass=assfValue: tSomeType;procedure SetValue(aValue: tSomeType);property Value:tSomeType read fValue write SetValue;End; В этом примере поле fValue модифицируется при помощи метода SetValue, ачитается напрямую.


Если свойство должно только читаться или только записываться, в его описании может присутствовать только соответствующий метод: tReadOnlyClass=assproperty NotChanged:tSomeType read GetNotChanged;End; В этом примере свойство доступно только для чтения. Попытка присвоитьзначение свойству NotChanged вызовет ошибку компиляции.Свойствам можно присваивать значения по умолчанию. Для этого служитключевое слово default: Property Visible:boolean read fVisible write SetVisible default TRUE;Это означает, что при запуске программы свойство будет установленокомпилятором в TRUE.Свойство может быть и векторным. В этом случае оно выглядит как массив: Property Points[index:integer]:tPoint read GetPoint write SetPoint;Для векторного свойства необходимо описать не только тип элементов массива,но также и тип индекса. После ключевых слов read и write должны идти именасоответствующих методов. Использование здесь полей массивов недопустимо.Метод, читающий значение векторного свойства, должен быть описан какфункция, возвращающая значение того же типа, что и элементы свойства, иимеющая единственный параметр того же типа и с тем же именем, что и индекссвойства: function GetPoint(index:integer):tPoint;Аналогично, метод, помещающий значения в такое свойство, должен первымпараметром иметь индекс, а вторым - переменную нужного типа. procedure SetPoint(index:integer; Value:tPoint);У векторных свойств есть еще одна важная особенность: некоторые классы вDelphi (списки tList, наборы строк tStrings и т.д.) “построены” вокругодного основного векторного свойства. Основной метод такого класса даетдоступ к элементам некоторого массива, а все основные методы являются какбы вспомогательными. Для упрощения работы с объектами подобного классаможно описать подобное свойство с ключевым словом default: type tMyList=assproperty list[Index:integer]:string read Getlist write Setlist; default;end; Если у объекта есть такое свойство, его можно не упоминать, а ставитьиндекс в квадратных скобках сразу после имени объекта: var MyList:tMyListBeginMyList.list[1]:=squo;First’; {Первый способ}MyList.[2]:=squo;Second’; {Первый способ}End; Употребляя ключевое слово default необходимо соблюдать осторожность, т.к.для обычных и векторных свойств оно употребляется в разных значениях.О роли свойств в Delphi красноречиво говорит тот факт, что у всех имеющихсяв распоряжении программиста стандартных классов 100% полей недоступны изаменены базирующимися на них свойствами. Того же правила следуетпридерживаться и при разработке собственных классов.
Наследование:Вторым “столпом” ООП является наследование. Этот простой принцип означает,что если необходимо создать новый класс, лишь немного отличающийся от ужеимеющегося, нет необходимости в переписывании заново уже существующегокода. Вы объявляете, что новый класс tNewClass=ass(tOldClass); является потомком или дочерним классом класса tOldClass, называемогопредком или родительским классом, и добавляете к нему новые поля методы исвойства.В Delphi все классы являются потомками класса tObject. Поэтому, если выстроите дочерний класс прямо от tObject, то в определении его можно неупоминать. Следующие два описания одинаково верны: tMyClass=ass(tObject);tMyClass=ass; Более подробно класс tObject будет рассмотрен ниже.Унаследованные от класса-предка поля и методы доступны в дочернем классе;если имеет место совпадение имен методов, говорят, что они перекрываются.Рассмотрим поведение методов при наследовании. По тому, какие действияпроисходят при вызове, методы делятся на три группы. В первую группуотнесем статические методы, во вторую - виртуальные (virtual) идинамические (dynamic) и, наконец, в третью - появившиеся только в Delphi 4перегружаемые (overload) методы.Статические методы, а также любые поля в классах-потомках ведут себяодинаково: можно без ограничений перекрывать старые имена и при этом менятьтип методов. Код нового статического метода полностью перекрывает (заменяетсобой) код старого метода: typetFirstClass=assfData:Extended;procedure SetData(aValue:Extended);end; tSecondClass=ass(tFirstClass)fData:Integer;procedure SetData(aValue:Integer);end; procedure tFirstClass.SetData(aValue:Extended);BeginfData:=0;End; procedure tFirstClass.SetData(aValue:Extended);BeginfData:=inherited SetData(0.99);End;


В этом примере разные методы с именем SetData присваивают значение разным полям с именем fData. Перекрытое (одноименное) поле предка недоступно впотомке. Поэтому два одноименных поля с именем fData приведены только дляпримера.В отличие от поля, внутри других методов перекрытый метод доступен приуказании ключевого слова inherited. По умолчанию методы объектов классовстатические - их адрес определяется еще на этапе компиляции проекта,поэтому они вызываются быстрее всего.Принципиально отличаются от статических виртуальные и динамические методы.Они должны быть объявлены путем добавления соответствующей директивыdynamic или virtual. С точки зрения наследования методы этих двух категорийодинаковы: они могут быть перекрыты в дочернем классе только одноименнымиметодоми, имеющими тот же тип.Полиморфизм. Виртуальные и динамические методыРассмотрим следующий пример. Пусть имеется некое обобщенное поле дляхранения данных - класс tFiled и три его потомка - для хранения строк,целых и вещественных чисел: typetFiled =lassfunction GetData:string; virtual; abctract;end; tStringFiled =lass(tFiled)fData:string;function GetData: string; override;end; tIntegerFiled =lass(tFiled)fData:Integer;function GetData: string; override;end; tExtendedFiled =lass(tFiled)fData:Extended;function GetData: string; override;end; function tStringFiled.GetData: string;BeginResult:ata;End; function tIntegerFiled.GetData: string;BeginResult:=tToStr(fData);End; function tExtendedFiled.GetData: string;BeginResult:=oatToStr(fData,ffFixed, 7, 2);End; function ShowData(aFiled:tFiled): string;BeginForm1.Label1.Caption:iled.GetData;End;

 

В этом примере классы содержат разнотипные поля данных fData, а также имеют унаследованный от tFiled виртуальный метод GetData, возвращающий данные в виде строки. Внешняя по отношению к ним процедура ShowData получает объектв виде параметра и показывает эту строку.Согласно правилам контроля соответствия типов (typecasting) ObjectPascal,объекту, как указателю на экземпляр класса, может быть присвоен адресэкземпляра любого из дочерних типов. Это означает, что в предыдущем примерев процедуру ShowData можно передавать объекты классов tStringFiled,tIntegerFiled, tExtendedFiled и любого другого потомка tFiled.Но какой (точнее, чей) метод GetData будет при этом вызван? Тот, которыйсоответствует классу фактически переданного объекта. Этот принципназывается полиморфизмом.Возвращаясь к рассмотренному выше примеру, отметим, что у компилятора нетвозможности определить класс объекта, фактически переданного в процедуруShowData на этапе компиляции. Механизм, позволяющий определить этот класспрямо во время выполнения называется поздним связыванием. Естественно,такой механизм должен быть связан с передаваемым объектом. Для этого служиттаблица виртуальных методов (Virtual Method Table, VMT) и таблицадинамических методов (Dynamic Method Table, DMT).Различие между виртуальными и динамическими методами заключается вособенности поиска адреса. Когда компилятор встречает обращение квиртуальному методу, он подставляет вместо прямого вызова по конкретномуадресу код, который обращается к VMT и извлекает оттуда нужный адрес. Такаятаблица есть для каждого класса. В ней хранятся адреса всех виртуальныхметодов класса, независимо от того, унаследованы ли они от предка илиперекрыты в данном классе. Отсюда и достоинства и недостатки виртуальныхметодов: они вызываются сравнительно быстро, однако для хранения указателейна них в таблице VMT требуется большое количество памяти.Динамические методы вызываются медленнее, но позволяют более экономнорасходовать память. Каждому динамическому методу системой присваиваетсяуникальный индекс. В таблице динамических методов класса хранятся индексытолько тех методов только тех динамических методов, которые описаны вданном классе. При вызове динамического метода происходит поиск в этойтаблице. В случае неудачи просматриваются DMT всех классов-предков впорядке их иерархии и, наконец, tObject, где имеется стандартный обработчиквызова динамических методов. Экономия памяти очевидна.Для перекрытия и виртуальных и динамических методов служит директиваoverride, с помощью которой (и только с ней!) можно переопределять оба этихтипа методов. typetParentClass=assfFirstFiled:Integer;fSecondFiled:longInt;procedure StaticMethod;procedure VirtualMethod1; virtual;procedure VirtualMethod2; virtual;procedure DynamicMethod1; dynamic;procedure DynamicMethod2; dynamic;end; tChildClass=ass(tParentClass)procedure StaticMethod;procedure VirtualMethod1; override;procedure DynamicMethod1; override;end;

 

Первый метод класса tChildClass создается заново, два остальных перекрываются. Создадим объекты этих классов: var Obj1: tParentClass; Obj2: tChildClass; Внутренняя структура этих объектов показана ниже. [pic]Первое поле каждого экземпляра каждого объекта содержит указатель на егокласс. Класс, как структура состоит из двух частей. Начиная с адреса, накоторый ссылается указатель на класс, располагается таблица виртуальныхметодов. Она содержит адреса всех виртуальных методов класса, включая иунаследованные от предков. Перед таблицей виртуальных методов расположенаспециальная структура, содержащая дополнительную информацию. В нейсодержатся данные, полностью характеризующие класс: имя, размерэкземпляров, указатели на класс-предок и т.д. Одно из полей структурысодержит адрес таблицы динамических методов класса (DMT). Таблица имеетследующий формат: в начале - слово, содержащее количество элементовтаблицы. Затем - слова, соответствующие индексам методов. Нумерацияиндексов начинается с –1 и идет по убывающей. После индексов идутсобственно адреса динамических методов. Следует обратить внимание на то,что DMT объекта Obj1 состоит из двух элементов, Obj2 - из одного,соответствующего перекрытому методу DynamicMethod1. В случае вызоваObj2.DynamicMethod2 индекс не будет найден в DMT Obj2, и произойдетобращение к DMT Obj1. Именно так экономится память при использованиидинамических методов.Как указывалось выше, указатель на класс указывает на первый виртуальныйметод. Служебные данные размещаются перед таблицей виртуальных методов, тоесть с отрицательным смещением. Эти смещения описаны в модуле SYSTEM.PAS: vmtSelfPtr =76vmtIntfTable =72vmtAutoTable =68vmtInitTable =64vmtTypeInfo =60vmtFiledTable =56vmtMethodTable =52vmtDynamicTable =48vmtClassName =44vmtInstanceSize =40vmtParent =36vmtSafeCallException =32vmtAfterConstruction =28vmtBeforeDestruction =24vmtDispatch =20vmtDefaultHandler =16vmtNewInstance =12vmtFreeInstance =8vmtDestroy =4


Поля vmtDynamicTable, vmtDispatch и vmtDefaultHandler отвечают за вызов динамических методов. Поля vmtNewInstance, vmtFreeInstance и vmtDestroyсодержат адреса методов создания и уничтожения экземпляров класса. ПоляvmtIntfTable, vmtAutoTable, vmtSafeCallException введены для обеспечениясовместимости с моделью объекта COM. Остальные поля доступны через методыобъекта tObject. В Object Pascal эта информация играет важную роль и можетиспользоваться программистом неявно. В языке определены два оператора - isи as, неявно обращающиеся к ней. Оператор is предназначен для проверкисовместимости по присвоению экземпляра объекта с заданным классом.

 

Выражение вида: AnObject is tObjectTypeПринимает значение True только если объект AnObject совместим по присвоениюс классом tObjectType, то есть является объектом этого класса или егопотомком.Оператор as введен в язык специально для приведения объектных типов. С егопомощью можно рассматривать экземпляр объекта как принадлежащий к другомусовместимому типу: with AObjectOfSomeType as tAnotherType do . . .От стандартного способа приведения типов использование оператора asотличается наличием проверки на совместимость типов во время выполнения:попытка приведения к несовместимому типу приводит к возникновениюисключительной ситуации eInvalidCast. После выполнения оператора as самобъект остается неизменным, но выполняются те его методы, которыесоответствуют присваиваемому классу.Вся информация, описывающая класс, создается и размещается в памяти наэтапе компиляции. Доступ к информации вне методов этого класса можнополучить, описав соответствующий указатель, называющийся указателем накласс или указателем на объектный тип (class reference). Он описывается припомощи зарезервированных слов class of. Например, указатель на классtObject описан в модуле SYSTEM.PAS и называется tClass. Аналогичныеуказатели определены и для других важнейших классов: tComponentClass,tControlClass и т.д.С указателем на класс тесно связано понятие методов класса. Такие методыможно вызывать и без создания экземпляра объекта - с указанием имени классав котором они описаны. Перед описанием метода класса нужно поставитьключевое слово class.Разумеется, методы класса не могут использовать значения, содержащиеся вполях класса: ведь экземпляра класса не существует!!! Методы класса служатдля извлечения внутренней информации класса. Ниже перечислены методы классаtObject.

 

Метод и Описание сlass function ClassName:ShortString Возвращает имя класса сlass function ClassNameIs(const Name:ShortString):Boolean Принимает значение True, если имя класса равно заданному сlass function ClassParent:tClass Возвращает указатель на родительский класс сlass function ClassInfo:pointer Возвращает указатель на структуру с дополнительными данными обопубликованных методах и свойствах. сlass function InstanceSize:Longint Возвращает размер экземпляра класса сlass function InheritsFrom (aClass: tClass):Boolean Возвращает True, если данный класс наследует от заданного сlass function MethodAddress(const Name:ShortString):Pointer Возвращает адрес метода по его имени (только для опубликованных методов) сlass function MethodName (Addres: pointer):ShortString Возвращает имя метода по его адресу (только для опубликованных методов)В Delphi 4 в класс tObject добавлены еще два виртуальных метода -AfterConstruction и BeforeDestruction. Как следует из названия, онивызываются сразу после создания экземпляра объекта и непосредственно передуничтожением.Перегрузка методовВ Delphi 4 появилась новая разновидность методов - перегружаемые.Перегрузка нужна для того, чтобы произвести одинаковые или похожие действиянад разнотипными данными. Перегружаемые методы описываются с ключевымсловом overload. TypetFirstClass=assE:extended;procedure SetData(aValue: Extended); overload;end; tSecondClass=ass(tFirstClass)I:integer;procedure SetData(aValue: Integer); overload;end;

 




Поиск по сайту:

©2015-2020 studopedya.ru Все права принадлежат авторам размещенных материалов.