Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...
Папиллярные узоры пальцев рук - маркер спортивных способностей: дерматоглифические признаки формируются на 3-5 месяце беременности, не изменяются в течение жизни...
Топ:
Эволюция кровеносной системы позвоночных животных: Биологическая эволюция – необратимый процесс исторического развития живой природы...
Комплексной системы оценки состояния охраны труда на производственном объекте (КСОТ-П): Цели и задачи Комплексной системы оценки состояния охраны труда и определению факторов рисков по охране труда...
Интересное:
Влияние предпринимательской среды на эффективное функционирование предприятия: Предпринимательская среда – это совокупность внешних и внутренних факторов, оказывающих влияние на функционирование фирмы...
Отражение на счетах бухгалтерского учета процесса приобретения: Процесс заготовления представляет систему экономических событий, включающих приобретение организацией у поставщиков сырья...
Национальное богатство страны и его составляющие: для оценки элементов национального богатства используются...
Дисциплины:
2018-01-04 | 205 |
5.00
из
|
Заказать работу |
|
|
OnePoint: TPoint; OneCircle: TCircle; implementation
Procedure TPoint.Draw (Newx, Newy: integer); begin
Forml.Canvas.Pixels [X,Y]: = clBtnFace; X:=NewX; Y:=NewY;
Forml.Canvas.Pixels [X,Y]:= clBlack; end;
Procedure TCircle.Draw(NewX, NewY: integer); begin
Forml.Canvas.Brush.Color:= clBtnFace; Forml.Canvas.Pen.Color:= clBtnFace;
Forml.Canvas.Ellipse (X-Radius, Y-Radius, X+Radius, Y+Radius); X:=NewX; Y:=NewY;
Forml.Canvas.Pen.Color:= clBlack; Forml.Canvas.Brush.Color:= clBlack;
Forml.Canvas.Ellipse (X-Radius, Y-Radius, X+Radius, Y+Radius); end;
Для создания объектов вызовем два конструктора. OnePoint:= TPoint.Create (10,10); OneCircle:= TCircle.Create (100,100,20);
В результате получим два объекта, каждый из которых имеет сво" собственный метод для рисования себя (рис. 3.2). OnePoint OneCircle
Рис. 3.2. Значение полей и состояние статического метода объектов OnePoint и
OneCircle после создания Различие между статическими, динамическими и виртуальными методам наступает при попытке присвоить родительскому объекту дочерний объект. Правила контроля соответствия типов (typecasting) языка Object Pascal гласят, что объекту, как указателю на экземпляр объектного типа может быть присвоен адрес любого экземпляра любого из его Оочерних типов. Пусть далее в программе выполняются операторы:
OnePoint OneCircle; OnePeint.Draw (100,100);
В этом случае после выполнения оператора присваивания значения полей X и 1 объекта OnePoint изменятся, а ссылка на код для метода Draw останется прежней (рис. 3.3). OnePoint OneCircle
Рис. 3.3. Значение полей и состояние статического метода объектов OnePoint и OneCircle после присваивания дочернего объекта родительскому объекту
Вызов метода OnePoint.Draw приведет к тому, что будет нарисована точка с новыми координатами (100,100). Иначе поведет себя объект OnePoint, если описать его метод Draw как виртуальный или динамический, так как в этом случае начнет действовать механизм ООП полиморфизм.
§3.8. Виртуальные, динамические и абстрактные методы. Полиморфизм. Информация о типах времени выполнения (RTTI)
|
При определении метода в классе он может быть описан как виртуальный или динамический. Для этого после описания метода в родительском классе указывается специальная директива: соответственно virtual или dynamic. Если метод переопределяется в потомке, то для того, чтобы начал работать механизм полиморфизма после описания метода необходимо указать директиву override. Попытка перекрытия с директивой не override, a virtual или dynamic приведет не к перекрытию, а к созданию нового одноименного метода и полиморфизм не будет работать. Попытка применить директиву override при перекрытии статического метода вызовет ошибку компиляции. Пример 3.8. Использование виртуальных методов в полиморфизме, interface type
TPoint = class X, X: Integer;
constructor Create (a, b: integer); procedure Draw (Newx, Newy: integer); virtual; end;
TCircle = class (TPoint) Radius: Integer;
Constructor Create (a, b, R: integer); procedure Draw (NewX, NewX: integer); override; end; var
OnePoint: TPoint; OneCircle: TCircle;
Если в каком-либо базовом типе метод был объявлен как виртуальный, то он остается виртуальным во всех классах-наследниках (в частности, и в наследниках наследников). То есть у наследников класса TCircle метод Draw также может быть перекрыт с использованием директивы override.
Отличие виртуальных методов от ранее рассмотренных статических метопов пр„ся после выполнения присваивания родительскомуобъекту дочернего
OnePoint:= OneCirele;
Если теперь вызвать метод OnePoint.Draw, то нарисуется окружность. Таким образом, объект OnePoint в результате произведенного присваивания изменил не только свои данные, но и свое поведение и стал вести себя не так как объекты своего класса, а так как объект дочернего класса.
Если описать другой класс, дочерний TPoint, и его объект:
Type
TSquare = class (TPoint) Edge: Integer;
constructor Create (a, b, E: integer);
procedure Draw (NewX, New!: integer); override; end; var
OneSquare: TSquare;
ii выполнить присваивание OnePoint:= OneSquare;
ro объект OnePoint станет вести себя как объект класса TSquare, вызов метода OnePoint. Draw нарисует квадрат. Таким образом, один и тот же родительский объект ведет себя по-разному (полиморфно), в зависимости от того какой дочерний объект был ему присвоен. Точнее, не весь объект, а виртуальные методы объекта OnePoint ведут себя иначе.
|
Для чего используется полиморфизм? Допустим, средствами ООП описывается совокупность явлений или процессов. Сначала необходимо выделить их общие черты поведения, при этом важно даже не каким образом делается что- иибо, а то, что, по сути, выполняется одно и то же действие. Все эти схожие черты описываются в классе-родителе. Те из них, которые не изменяют своего содержания при переходе от общего к частному, реализуются в виде статических методов, те же, которые изменяются - как виртуальные или динамические методы, чтобы потом было возможно их перекрыть в классах-потомках.
Теперь для этой иерархии можно написать некий алгоритм, который выполняет некоторое общее для всех объектов действие. В качестве конкретного объекта, выполняющего это действие нужно описать объект класса-родителя, lie л и теперь присвоить этому объекту какой-либо из его потомков, то алгоритм будет делать одно и то же, по сути, действие, но по-разному. Таким образом, один и тот же алгоритм сможет правильно обрабатывать разные виды объектов! Использование таких возможностей ООП может значительно упростить алгоритм программы в целом.
Прим. яительно к нашему примеру полиморфизм заключается в том, что все геометрические фигуры - наследники класса «точка» умеют себя нарисовать, но псе делают это по-разному. Например, если имеется базовый класс графических объектов TPoint и ряд наследующих ему объектов геометрических фигур и в каждом из этих классов определен свой виртуальный метод Draw, рисующий эту фигуру, то можно написать в программе: var GraphArray: array [1..10] of TPoint;
for i:= 0 to 10 do GraphArray[i].Draw;
Если в массив GraphArray будут загружены объекты разных типов- маследников TPoint, то несмотря на то, что обращение для каждого из них происходит как к объекту родительского класса, вызываться будет виртуальный метод Draw именно этого объекта.
Различие между виртуальными и динамическими методами
В случае динамических и виртуальных методов у компилятора нет иозможности на этапе компиляции и компоновки жестко связать имя метода с адресом оперативной памяти, где находится его исполняемый код. Нужен механизм, позволяющий определить это прямо во время выполнения. Этот механизм называется поздним связыванием, он реализуется или через таблицу пнртуальньр: методов (Virtual Method Table - VMT) или "через таблицу динамических методов (Dynamic Method Table - DMT). В соответствии с этими
|
механизмами в Delphi имеется два варианта реализации позднего связывания виртуальные и динамические методы. Синтаксис у обеих этих директив один и тот же, результат - тоже. Различие заключается во внутреннем механизме, используемом компилятором для организации позднего связывания.
Виртуальные методы основаны на таблице виртуальных методов (VMT), которая представляет собой массив адресов всех виртуальных методов каждого. Когда компилятор встречает обращение к виртуальному методу объекта, он подставляет код, который обращается к VMT класса этого объекта и извлекает оттуда нужный адрес. Такая таблица заводится для каждого класса. В ней хранятся адреса всех виртуальных методов класса, независимо от того, были они перекрыты или нет в данном классе. В конечном счете, это приводит к эффекту распространения адресов таблицы виртуальных методов через всю иерархию классов (даже для методов, которые не переопределялись). Отсюда вытекают достоинства и недостатки виртуальных методов: они вызываются сравнительно быстро, однако для хранения указателей на них в таблицах VMT требуется большое количество памяти.
Вызовы динамических методов производятся при помощи уникального номера, определяющего метод. В таблице динамических методов класса хранятся индексы и адреса только тех динамических методов, которые описаны в данном классе. При вызове динамического метода происходит поиск в этой таблице; в случае неудачи просматриваются таблицы DMT всех классов-предков в порядке иерархии и, наконец, TObject, где имеется стандартный обработчик вызова динамических методов. Таким образом, поиск кода вызываемого метода в общем случае является более медленным, чем простой одношаговый вызов через VMT. Однако для больших и глубоких иерархий, использование динамических методов вместо виртуальных может привести к значительной экономии памяти. Пример 3.9. Описание двух классов с динамическими и виртуальными методами
Interface type
TClassl = class X, У: Integer; procedure StatMethod; procedure VirtualMethodl; virtual; procedure VirtualMethod2; virtual; procedure DynamicMethodl; dynamic; procedure DynamicMethodZ; dynamic; end;
TClass2 = class (TClassl) procedure StatMethod; procedure VirtualMethodl; override; procedure DynamicMethodl; override; end; var
|
|
История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...
Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...
Своеобразие русской архитектуры: Основной материал – дерево – быстрота постройки, но недолговечность и необходимость деления...
Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!