Приведение к родительскому типу Назад В начало Вперед

Возможно присвоение переменной типа ссылки на родительский 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
  ...