Приведение к родительскому типу |
Возможно присвоение переменной типа ссылки на родительский obj-интерфейс значения типа ссылки на obj-интерфейс потомок без явного приведения типа. При этом результат такого присвоения, вообще говоря, не эквивалентен явному приведению типа: при неявном приведении, переменной типа ссылки на родительский obj-интерфейс присваивается значение ссылки на потомка и все вызовы методов с использованием этой ссылки будут полиморфными (т.е. будут вызываться методы потомка). При явном приведении типа, ссылка изменяется и реально указывает на тот объект к типу которого было приведение.
Пример 1.
objInterface parent; procedure A; end; objInterface child1 (parent); procedure B; end; objInterface child2 (parent); Procedure B; end; vipInterface vipChild implements child1, child2; interface vipChild; ... procedure child1.A; // реализация метода child1.A { ... } procedure child2.A; // реализация метода child2.A { ... } implementation child1.B, child2.B procedure B; { ... } ... end. ... var pParent : parent; pChild1 : child1 (vipChild); pChild2 : child2 (vipChild); pParent := pChild1; // pParent содержит ссылку на child1 pParent.A; // вызовется метод C1_A pParent := pChild2; // pParent содержит ссылку на child2 pParent.A; // вызовется метод C2_A ...
Таким образом, открываются новые возможности для использования полиморфизма.
Если vip-интерфейс реализует obj-интерфейс потомок, то возможно приведение ссылки на этот vip-интерфейс ( или ссылки на любой его obj-интерфейс ) к ссылке на родителя. Результатом такого приведения будет ссылка на первого ( в списке имплементации ) потомка данного obj-интерфейса.
Пример 2.
... var pParent : parent; pChild2 : child2 (vipChild); // неявное приведение типа pParent := pChild2; // pParent содержит ссылку на child2 pParent.A; // вызовется метод C2_A // приведение к первому интерфейсу-потомку pParent := Parent (pChild2); // pParent содержит ссылку на child1 pParent.A; // вызовется метод C1_A ...