Пример простой иерархической структуры
Наследование имеет определенные правила совместимости типов объектов. При этом производный тип (тип-потомок) совместим по типу со своим предком:
- между экземплярами объекта;
- между указателями на экземпляры объектов;
- между формальными и фактическими параметрами.
Совместимость имеет место только от потомка к предку. Другими словами, производные типы можно использовать вместо родительских, но не наоборот. Это определяет правила присваивания для переменных типа объект. Они состоят в том, что переменным можно присваивать значения этого же типа и любого производного от него, т. е. предку можно присвоить значение объекта-потомка. Обратное присваивание недопустимо. Производный тип всегда получается не меньшим, чем тип предка (родительский). В результате выполнения присваивания будут скопированы от источника только те поля, которые являются общими для обоих типов.
Полиморфизм
Основные понятия
Полиморфизм - это возможность иметь несколько методов с одним и тем же именем для различных объектов одной иерархии, т. е. средство для развития объектов в потомках. Оно реализуется тем, что объект-потомок может переопределять, т. е. заменять методы предка на новые с теми же именами. Какой из методов будет выполняться при. обращении к методу с заданным именем, определяется типом объекта (предок или потомок) и используемого метода.
Методы объектов по способам их переопределения могут быть статические, виртуальные и динамические (подкласс виртуальных). В соответствии с этим процесс установки взаимосвязи объектов и методов может быть:
- ранним - во время компиляции - для статических методов;
- поздним - во время выполнения программы (вызова метода) для виртуаль
ных методов.
Статические методы
По умолчанию все методы статические. Все ранее рассмотренные методы -статические. Такое наименование методов связано с тем, что определение и размещение ссылок на них (для вызова методов) производится на этапе компиляции и на все время выполнения программы. Это - раннее связывание.
Список формальных параметров статических методов может быть различным у метода предка и методов потомков, переопределяющих (заменяющих) этот метод предка.
Со статическим методом связан способ наследования. Если в объявлении потомка появляется метод с тем же именем, что и у предка, то в этом типе и во всех его потомках этот метод будет переопределен. Таким образом, потомки могут использовать переопределенные ими методы предка. Предок может вызвать только свои методы; методы потомков для него недоступны. Таким образом, при использовании статических методов полиморфизм распространяется от текущего уровня иерархии вниз, к потомкам.
Действия компилятора при обработке методов иерархии объектов для статических методов:
1) при вызове метода компилятор устанавливает тип объекта, вызывающего
метод;
2) затем он ищет метод в пределах этого типа; найдя его, компилятор назначает вызов этого метода;
3) если метод не найден, то компилятор рассматривает тип непосредственно
го предка и ищет метод в его объявлении:
а) если метод с таким именем найден, формируется вызов метода этого
предка;
б) если метод не найден в типе ближайшего предка, компилятор переходит
к типу предка, следующего в иерархии предков; и так до тех пор, пока
не будет найден вызванный метод;
в) если компилятор, дойдя до верхнего уровня иерархии, не найдет метод,
он выдаст сообщение об ошибке номер 44 периода компиляции:
Field identifier expected - ожидается идентификатор поля.
Это сообщение выдается, если идентификатор не соответствует имени поля переменной типа RECORD или типа OBJECT.
Существенное ограничение статических методов: если метод предка вызывает другие методы, то это могут быть только методы предка, даже если потомок имеет свои собственные методы с таким же именем метода. Этот недостаток предопределен тем, что связь объекта с методом производилась на этапе компиляции, статически, на все время выполнения программы. Этот недостаток статических методов устраняется использованием виртуальных методов.
Ограничение статических методов рассмотрим на примере программы листинга 3. Из него видно существенное ограничение статических методов: если метод (Metl объекта ObjName1) предка вызывает другие методы (Met2), то это могут быть только методы предка (objNamel .Met2), даже если потомок имеет свои собственные методы с таким же именем метода (objName2 .Met2). В примере листинга 3 оператор V2.Metl; вызывает выполнение метода ObjNamel .Metl, который вызывает метод ObjNamel .Met2, несмотря на то что тип ObjName2 имеет свой собственный метод ObjName2 .Met2. Это происходит потому что связь объекта с методом производилась на этапе компиляции. Схематично это представлено на рис. 2.
Листинг 3.Вызовы статических методов предка и потомка.
Program novirt1; Uses Crt;
Type ObjName1 = object { - объявление объекта-предка } Fl1 : integer; { - поле }
Procedure Met1; { - методы }
Procedure Met2;
End;
ObjName2 = object (ObjName1) { - объявление потомка } Procedure Met2; { - замена статического метода } End;
{ --- Методы объекта ObjName1 ------- }
Procedure ObjName1.Met1;
Begin Met2; { - вызов только метода ObjName1.Met2 !!} End;
Procedure ObjName1.Met2;
Begin FL1 := 12;
Writeln ( 'Работает метод ObjName1.Met2: FL1 = ', FL1) End;
{ ----- Метод объекта ObjName2 ------ }
Procedure ObjName2.Met2; Begin FL1 := 34;
Writeln ( 'Работает метод ObjName2.Met2: FL1 = ', FL1) End;
Var VI:ObjName1; { - переменная объектного типа - предка }
V2 : ObjName2; { - " " " потомка }
{--------- - Основная программа }
Begin ClrScr;
Assign (Output, 'Inovirt.res'); Rewrite (Output);
Writeln ( 'ОБЪЕКТЫ, СТАТИЧЕСКИЕ МЕТОДЫ1 );
Writeln ('Работаем с VI - экземпляром типа предка');
VI.Met1; {- вызывается метод Met1 для экземпляра VI - предка }
{ Met1 вызывает метод ObjName1.Met2 - предка }
V1.Met2; { - непосредственно вызывается метод ObjName1.Met2; }
Writeln ('Работаем с V2 - экземпляром типа потомка');
V2.Met1; { - вызывается метод Met1 для экземпляра V2 - потомка; Met1 вызывает метод ObjName1.Met2 - предка, а не ObjName2.Met2 - потомка - в этом - ограничение }
V2.Met2 { - непосредственно вызывается метод ObjName2.Met2; }
Close (Output);
End.
Рис. 2
Схема ограничения вызова переопределенных статических методов
Дата добавления: 2019-12-09; просмотров: 534;