рефераты конспекты курсовые дипломные лекции шпоры

Реферат Курсовая Конспект

Виртуальные методы. Конструкторы. Раннее и позднее связывание. Полиморфизм.

Виртуальные методы. Конструкторы. Раннее и позднее связывание. Полиморфизм. - раздел Программирование, Объектно-ориентированное программирование В Приведенной Выше Программе При Описании Объектов Некоторые Методы Заданы Ка...

В приведенной выше программе при описании объектов некоторые методы заданы как виртуальные (virutal). В этом случае перед вызовом какого-либо метода соответствующего экземпляра класса (переменной объектного типа) этот экземпляр (объект) должен быть инициализирован с помощью специального метода, называемого конструктор (constructor). Обычно в Borland Pascal ему давалось имя Init, а в Delphi - Create. Конструктор у объекта в языке Object PASCALможет быть не один, но у каждого из них должно быть свое имя. В C++ и в Java имя конструктора всегда совпадает с именем класса, но конструкторов также может быть несколько. При этом они должны отличаться списком параметров конструкторов. В зависимости от способа инициализации иногда бывает целесообразно вызывать тот или иной конструктор. Например, для окружности в ряде случаев можно задавать некое значение радиуса "по умолчанию". Допустим, это 50 пикселей. Тогда можно написать следующий конструктор (назовем его Init1):

constructor tCircle.Init1(X_,Y_:integer);

begin

Init(X_,Y_,50)

end;

При вызове такого конструктора надо задавать только координаты окружности.

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

Например, нельзя определить в tDot метод MyShow(X_,Y_:Integer);virtual, а в tCircle задать MyShow(X_,Y_,R_:Integer);virtual. Зато, благодаря виртуальным методам, благодаря наличию полиморфизма, можно не переписывать несколько раз тела этих методов, которые выглядят одинаково, но относятся к разным объектам. Например, вместо описания в классе tCircle метода MoveBy, буква в букву повторяющего метод MoveBy для класса tDot в случае статических методов Show и Hide:

procedure tCircle.MoveBy(dX,dY:Integer);

begin

Hide;

X=X+dX;

Y=Y+dY;

Show;

end;

и множества таких же (для tArc любого и нового типа фигуры), можно описать методы Show и Hide в иерархии как виртуальные, и сделать описание процедуры MoveBy только один раз для tDot, а для потомков использовать наследование. При этом виртуальные процедуры Hide и Show будут выполняться по-своему для своей фигуры, т.к. для виртуальных методов они берутся из класса, к которому относится вызывающий их объект, (например, из tCircle для объекта aCircle), а не из класса, в котором компилируется метод прародителя tDot для метода MoveBy. Методы Show и Hide, естественно, перекрываются в каждом классе-потомке, т.е. имеют разные реализации для разных фигур.

Надо отметить, что конструкторы в Turbo Pascal не могли быть виртуальными, хотя и могли наследоваться как обычные статические методы. В Object PASCAL начиная с Delphi 2.0 конструкторы можно объявлять виртуальными, хотя без особой необходимости не следует этого делать.

Текст модуля, в котором описан тип tArc, создан независимо от текста модуля Figures и использует только его интерфейсную часть и комбинированный бинарный файл

Figures.dcu. Он может быть даже намного позже компиляции файла .dcu!). Но экземпляры tArc свободно могут пользоваться унаследованными виртуальными методами MoveBy, MoveTo. При этом MoveBy, MoveTo вызывают методы Show и Hide, которые для Arc свои, вновь написанные, и скомпилированы они гораздо позднее, чем модуль Figures! Это — позднее связывание: вызов методов (имени методов с его реализацией в каком либо классе) определение, к какому классу относится виртуальный метод, происходит во время выполнения программы. А статические правила имеют раннее связывание, на этапе компиляции. При этом какой тип соответствуетметоду в программе, метод такого типа и вызывается. То есть если написан вызов Row в реализации метода tDot.moveBy, то будет вызван метод tDot.Show даже в случае вызова aCircle.moveBy(…). Если же метод Show виртуальный, вызовется tCircle.Show.

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

Позднее связывание: для каждого класса создается таблица виртуальных методов (VMT) (Virtual Methods Table). VMT содержит для каждого метода указатель на адрес кода, выполняющего метод. Экземпляры объектного типа не содержат VMT (она едина для всего класса), а только ссылку на нее. Эта ссылка используется в момент вызова виртуального метода объектом. А так как каждый объект имеетссылку на метод, соответствующийсвоему классу, то вызывается метод из соответствующего класса. Как бы работала программа, если бы все методы были описаны как статические? По наследованию вызвался бы метод для прародителя tDot, и методы Show и Hide в tDot.MoveBy или tDot.MoveTo всегда воспринимались бы "настроенными" на тот тип, к которому все это относилось в момент компиляции, то есть к tDot. Значит, всегда двигалась бы точка, а не окружность или дуга!

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

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

type

tDot=

object(tLocation)

procedure Show;

procedure Hide;

procedure MoveBy(dX,dY:integer);

...

end;

tCircle=

object(tDot)

procedure Show; {перекрывается статический метод}

procedure Hide; {перекрывается статический метод}

{процедура MoveBy не перекрывается, она наследуется}

...

end;

tArc=

object(tCircle)

...

procedure Show; {перекрывается второй раз}

procedure Hide; {перекрывается второй раз}

{процедура Move не перекрывается, она наследуется}

...

end;

...

{-реализация методов-}

procedure tDot.MoveBy(dX,dY:integer);

begin

Show;

X:=X+dX;

Y:=Y+dY;

Hide;

end;

...

var aCircle:tCircle;

aArc:tArc;

...

При вызове aArc.MoveBy(5,10) вызовется метод tDot.MoveBy, т.к. он наследуется классами tCircle и tArc от класса tDot, и ни в tCircle, ни в tArc этот метод не перекрыт. В методе tDot.MoveBy вызываются методы Show и Hide. Все упомянутые методы описаны как статические. Поскольку статические методы встраиваются в исполняемый код программы "сразу", на этапе компиляции программы, они вызываются именно для того типа, в котором определены, то есть это tDot.Show и tDot.Hide . Поэтому в нашем случае tDot.Show покажет, а tDot.Hide погасит точку на экране с координатами дуги aArc.X и aArc.Y. По-видимому, это несколько не то, что бы мы хотели. Для того, чтобы двигалась дуга, процедуры Show и Hide в tDot надо пометить как виртуальные:

procedure Show;virtual;

procedure Hide;virtual;

а во всей иерархии объектов (tCircle, tArc и т. д.) надо пометить их как перекрытые:

procedure Show;override;

procedure Hide;override;

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

Как теперь будет осуществляться вызов aArc.MoveBy(5,10)? В методе tDot.MoveBy, который вызывается благодаря наследованию, вызываются методы Show и Hide из класса вызывающего их объекта, т.е. tArc.Show и tArc.Hide, поскольку методы помечены как виртуальные. В результате рисуется и перемещается дуга.

Что бы произошло, если бы в tCircle виртуальные методы Show и Hide были перекрыты (переопределены так, что рисовалась и скрывалась бы окружность), в tArc они не были еще раз перекрыты и наследовались бы от tCircle? В таблице виртуальных методов каждого класса хранятся указатели на виртуальные методы для данного класса, а также для всех его прародителей. Если виртуальный метод в классе не перекрыт, указатель для метода настраивается на метод ближайшего прародителя, в котором метод определен или перекрыт. Поэтому в случае двигалась бы окружность.

type tFigure=tDot;

Procedure moveFigure(var aFigure:tFigure,dx,dy,integer)

begin

aFigure.moveBy(dx,dy)

end;

В приведенном примере используется полиморфизм: на этапе компиляции программы неизвестно, какого типа объект aFigure вызовет метод moveBy. А поскольку реализация метода осущесталяется с помощью виртуальных методов Show и Hide , их вызовы будут осуществляться для класса, к которому относится вызывающий их объект aFigure, а не для класса tDot.

 

– Конец работы –

Эта тема принадлежит разделу:

Объектно-ориентированное программирование

На сайте allrefs.net читайте: "Объектно-ориентированное программирование"

Если Вам нужно дополнительный материал на эту тему, или Вы не нашли то, что искали, рекомендуем воспользоваться поиском по нашей базе работ: Виртуальные методы. Конструкторы. Раннее и позднее связывание. Полиморфизм.

Что будем делать с полученным материалом:

Если этот материал оказался полезным ля Вас, Вы можете сохранить его на свою страничку в социальных сетях:

Все темы данного раздела:

Object PASCAL
(72 часа) Вадим Валериевич Монахов, доцент кафедры вычислительной физики СпбГУ Введение   1.1. Основной принцип ст

Алфавит языка PASCAL. Идентификаторы.
Основной алфавит языка PASCAL состоит из латинских букв и цифр. Буквы: ABCD...XYZ — заглавные (прописные), abcd...xyz — строчные, а также знак _

Простые и составные специальные символы, используемые на ПК.
Перечисленный ниже набор несколько расширяет стандарт PASCAL, однако на ПК является стандартом de facto. Простые специальные символы: + Плюс – “сложени

Стандартные типы данных. Двоичное представление чисел и дополнительный код.
Целые типы Byte: 0..255 — байтовый (1 байт) ShortInt: -128..127 — короткое целое (1 байт) Word: 0..65535 — 16-ричное слово (2 байта) Inte

Арифметические операторы.
Бинарные полиморфные (тип результата определяется по правилам приведения типов, см. далее): + сложение (все целые и вещественные типы, строковые типы, множества).

Логические операторы и операции отношения.
Логические операторы: and логическое "И". Пример: a and b or логическое "ИЛИ": a or b xor логическое "исключающее ИЛИ": a xor b not

Потеря точности, потеря порядка и переполнение при арифметических операциях.
Пусть x1 – арифметическая переменная real, x2 – вещественная extended. Тогда выполнение присваиваний x2:=1+1e-14 даст 1.00000000000001, а x1:=1+1e-14 даст 10000000000000,т.к. числа real имеют всего

Структура простейшей программы.
В PASCAL любое число пробелов, символов <TAB> или переносов на новую строку везде приводится к одному пробелу (конечно, кроме строковых выражений). Имя файла с текстом программы должно быть т

Простейшие операторы языка Object PASCAL
2.9.1. Пустой и составной операторы. Операторы в языке PASCAL разделяется символом ";". Пустой оператор — это просто пустая строка (или эквивален

Процедуры и функции. Формальные и фактические параметры. Передача параметров по ссылке, по значению и через указатель.
Процедуры по своей структуре напоминают независимую программу, вложенную в основную программу. Главное их отличие в том, что они, как правило, имеют параметры, передаваемые из внешнего программного

Локальные и глобальные переменные. Побочный эффект функции. Вложенность процедур и функций. Правила видимости.
В приведенных выше примерах часть переменных описана в блоке описания переменных программы. Такие переменные называются глобальными. Они существуют в любой момент выполнения программы. Другая часть

Модули. Секции декларации, интерфейса и реализации. Области видимости.
На самом деле общая структура модуля при наличии в нем класса несколько сложнее. Обсудим ее более подробно. Написание собственного модуля (unit) начинается с указания имени модуля. В нашем

Классы, экземпляры класса, наследование, иерархия.
Объектный тип (например, tDot) называется классом. Переменная данного типа — объект или, что то же самое, экземпляр класса. То есть при задании Var dDot:tDot переменная dDot – это

Пример объектно-ориентированной программы: движение фигур по экрану.
unit Figures; interface uses…; type tLocation= object X,Y:Integer; procedure Init(X_,Y_:Integer); function GetX:Integer;

Динамические объекты. Выделение и высвобождение памяти. Деструкторы.
Указатель на объект устроен так же, как обычные указатели:    

Правила присваивания. Совместимость типов для объектов.
Для потомков при использовании их "на месте" прародителей любого уровня имеется два основных варианта совместимости типов (по вызовам и по присваиваниям) между: 1. экземплярами о

Пример на создание, присваивание и уничтожение динамических объектов.
Unit FigDemo1; Uses…,Figures,FigArc; var FigKey:char; Ang1_ini,Ang2_ini,R_ini,X_ini,Y_ini:Integer; newX,newY,newR:Integer; pFigure:tpDot; outside:Boolea

Пример динамического выделения и высвобождения памяти для однонаправленного списка объектов.
Создадим список, в котором хранятся различные фигуры — объекты иерархии с классом-прародителем tDot. Введем запись типа "узел", ссылающийся на одну фигуру и один другой (предыдущий) узел:

Очередь, стек, двунаправленный список.
Совершенно аналогичным образом можно создавать объект — двунаправленный список, в котором каждый узел имеет указатели как "влево" (на предыдущий узел), так и "вправо" (на послед

Классы, объекты, поля и методы.
В Object Pascal класс — тип записи, который может иметь в своем составе поля данных и методы (а также свойства, но о них будет отдельный разговор). Пример описания класса и переменн

Свойства.
В Delphi пожелание ООП "не обращаться из программы к полям, а действовать через методы" нашло отражение в новом для ООП принципе — свойствах объекта. Свойство определяется

Создание и уничтожение объектов. Конструкторы и деструкторы.
В Object Pascal объекты могут быть только динамическими! Любая переменная объектного типа — это указатель, но доступ к объекту идет без 'шляпки', а создание нового объекта осуществляется не операто

Наследование. Статические, виртуальные, динамические и абстрактные методы.
Все классы Delphi — потомки класса tObject. Если нет указания, какой класс является прародителем, значит, это tObject. Определение tMyObject=class ... end; полно

Области видимости объектов.
В Delphi существуют зарезервированные слова public ("общие"), protected ("защищенные") и private ("личные") для определения специальных правил видимости областей кода

Обработка исключительных ситуаций.
Во время работы программы часто встречаются исключительные ситуации: деление на 0, отсутствие места на диске или попытка писать на защищенную для записи дискету, ошибочный символ при вводе (наприме

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

События и их делегирование. Обработка событий.
События — это свойства процедурного типа. Их название принято начинать с префикса "on". Для описания события некого типа (как описать новый тип события будет рассказано далее) в объекте н

Методы класса и указатели на класс.
Некоторые методы бывает нужно вызывать без создания экземпляра класса (например, для получения информации о имени класса, размере экземпляра класса и т.п.). Такие методы называются методами класса

Дополнительные возможности Object Pascal.
4.17.4. Функции а) могут возвращать значения определенных пользователем типов, включая сложные; б) внутри каждой функции предопределена доступная по чтению и записи локальн

Визуальное проектирование в среде Delphi.
Перед началом работы обычно надо настроить пути к библиотеке Delphi, а в Delphi 3.0 также установить пакеты. Это связано с тем, что Windows 95 (и, тем более, NT 4.0) имеет индивидуальные настройки

Создание экранных форм. Инспектор объектов.
При входе в Delphi автоматически открывается проект "по умолчанию". Изначально это проект с пустой экранной формой, на которой пунктиром показана сетка, к которой идет привязка для выравн

Палитра компонентов.
Мы будем описывать только наиболее важные свойства и события для компонентов и перечислим только наиболее часто используемые компоненты из стандартных библиотек Delphi 3.0. Для Delphi 2.0 практичес

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

Особенности разработки DLL
Работа программ с DLL (Dynamic Link Library) поддерживается операционной системой, а не компилятором какого-либо языка программирования. Они представляют собой универсальный механизм использования

ActiveX
Подпроцессы (Threads) Для создания дополнительного подпроцесса в программах Delphy предназначен специальный модуль (в репозитории он представлен пиктограммой Thread Object

Использование библиотек OpenGL и GLU
5.21. Создание программистом собственного компонента Литература 1. В.В.Фаронов . Delphi 6. Учебный курс.- М.:"Нолидж", 2001.- 608 с.

Хотите получать на электронную почту самые свежие новости?
Education Insider Sample
Подпишитесь на Нашу рассылку
Наша политика приватности обеспечивает 100% безопасность и анонимность Ваших E-Mail
Реклама
Соответствующий теме материал
  • Похожее
  • Популярное
  • Облако тегов
  • Здесь
  • Временно
  • Пусто
Теги