Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Полиморфизм. Виртуальные методы

Наследование и переопределение.

 

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

Type Circle = Object (Point)

Radius: integer;

end;

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

Var ObCircle: Circle;

begin

ObCircle.Init (30, 40);

…………………….

Таким образом, наследование на языке Turbo Pascal может быть описано таким образом:

Type <имя нового объекта> = Object (имя объекта-родителя)

< новые поля данных>

<новые методы потомка>

end;

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

Переопределение – это свойство объектов, позволяющее переопределить в объекте-потомке методы объекта-родителя, оставив при этом прежние имена подпрограмм:

Type Circle =Object (Point)

Radius: integer;

Procedure Init (a, b, R: integer);

Procedure SwitchOn;

Procedure SwitchOff;

Procedure Move (dx, dy: integer);

Function GetR: integer;

End;

Procedure Circle.Init (a, b, R: integer);

begin

Point.Init (a, b);

Radius:=R;

end;

…………………………..

Procedure Circle.SwitchOn;

begin

v:=true;

Graph.Circle (x, y, R);

end;

…………………………

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

<родитель>::=<наследник>

При этом копируются только те поля, которые являются общими для обоих типов.

Как правило, основная часть работы по написанию объектно-ориентированных программ состоит в построении иерархии объектов.

 

 

Имеем описания двух объектовых типов:

Type Point =Object

x, y: integer;

v: boolean;

Procedure Init (a, b: integer);

Procedure SwitchOn;

Procedure SwitchOff;

Procedure Move (dx, dy: integer);

Function GetX: integer;

Function GetY: integer;

End;

Type Circle =Object (Point)

Radius: integer;

Procedure Init (a, b, R: integer);

Procedure SwitchOn;

Procedure SwitchOff;

Procedure Move (dx, dy: integer);

Function GetR: integer;

End;

Алгоритм метода Move похож для обоих типов, поэтому определим его для объектового типа Point, а тип-потомок Circle унаследует его без переопределения:

Procedure Move (dx, dy: integer);

begin

SwitchOff;

x:=x+dx; y:=y+dy;

SwitchOn;

end;

Имеем экземпляры двух объектов рассматриваемых типов:

Var ObPoint: Point;

ObCircle: Circle;

В случае такого описания объектовых типов при выполнении следующих двух сообщений: ObPoint.Move (20, 30); ObCircle.Move (10, 15); возникает коллизия. Причиной ее является то, что унаследованный метод Move жестко связан с методом Point, поэтому метод Move всегда будет вызывать метод Point.SwitchOff. Связь этих методов является статической, т.к. она была определена при компиляции. Таким образом, при выполнении сообщения ObCircle.Move (10, 15); на экране также будет перемещаться точка, а не круг.

 
 

 


Таким образом, если мы имеем один метод для различных объектов, то необходимо разорвать статическую связь, а также обеспечить возможность для Move подключать либо метод Point.SwitchOff, либо метод Circle.SwitchOff в зависимости от того, какой объект вызывает Move. Такой механизм называется динамическим или поздним связыванием и достигается с помощью применения виртуальных методов.

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

Type Point =Object

…………………….

Constructor Init (a, b: integer);

Procedure SwitchOn; virtual;

Procedure SwitchOff; virtual;

Procedure Move (dx, dy: integer);

…………………….

End;

Type Circle =Object (Point)

…………………….

Constructor Init (a, b, R: integer);

Procedure SwitchOn; virtual;

Procedure SwitchOff; virtual;

…………………….

End;

В этом случае, при выполнении цепочки вызовов ObPoint.Move (20, 30); ObCircle.Move (10, 15); один и тот же метод Move будет работать по-разному в зависимости от того, какой объект этот метод вызывает. Такое свойство называется полиморфизмом.

При виртуализации методов должны выполняться следующие условия:

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

2. Если переопределяется реализация виртуального метода, то заголовок заново определяемого виртуального метода в производном типе или объекте не может быть изменен.

3. В описании объекта должен обязательно описываться специальный метод (обычно это метод, выполняемый первым – метод инициализации). Слово Procedure, при этом, заменяется ключевым словом Constructor. Это особый вид процедуры, определяющий установочную функцию для механизма виртуальных методов. Суть механизма виртуальных методов состоит в том, что каждый объектный тип (но не экземпляр) имеет свою таблицу виртуальных методов,которая содержит размер объекта и адреса кодов виртуальных методов. При вызове виртуального метода каким-либо экземпляром местонахождение кода определяется по таблице. Конструктор же определяет связь между экземпляром объекта и таблицей виртуальных методов. Конструкторы могут быть только статическими, хотя внутри его могут быть использованы виртуальные методы.

Выбор метода. Необходимо делать метод виртуальным, если есть хотя бы малейшая вероятность того, что понадобится переопределение этого метода. Это обеспечивает расширяемость программ. С другой стороны, если объект имеет хотя бы один виртуальный метод, то для него создается таблица виртуальных методов и каждый вызов виртуального метода происходит через обращение к таблице. Таким образом, выбор надо делать между некоторым малозаметным увеличением скорости вычислений при эффективном использовании памяти, которое дают статические методы, и гибкостью, которую представляют виртуальные методы.

 

<== предыдущая лекция | следующая лекция ==>
Объекты и свойства инкапсуляции | Обработка ошибок при работе с динамическими объектами
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 479; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.02 сек.