Child(p) - это не сужение, а, скорее, возведение, расширение к наследнику. Операция недопустимая. К базовому - можно. К наследнику - нельзя. В vip нет виртуальных функций в чистом виде, поэтому и попытка реализовать метод Equals на vip-интерфейсах не имеет смысла. Зато эта задача в принципе легко решается с помощью obj-интерфейсов.
Код: Выделить всё
objinterface IComparable
property Criteria1: SomeType1;
...
property CriteriaN: SomeTypeN;
end;
Тогда утверждение равенства звучит так: "две реализации IComparable равны, если все или некоторая комбинация их критериев равны". На месте CriteriaXXXX может стоять любая значимая характеристика из предметной области. То есть, в принципе можно сравнивать две совершенно различные реализации. Например, если критерием равенства является степень гладкости, плоскости, ровности объекта (Plainness), то Стол и Дорога вполне могут быть "равны".
Если нужно организовать сравнение объектов, "произрастающих" от одного корня, то функцию сравнения можно разместить в базовом объекте:
Код: Выделить всё
vipinterface Base(IComparable);
function Equals(Another: IComparable): boolean;
end;
interface Base;
...
property Criteria1: SomeType1 read ...;
...
function Equals(Another: IComparable): boolean;
{
var Me: IComparable;
Me := IComparable(Self);
Result :=
(Me.Criteria1 = Another.Criteria1)
and (Me.Criteria2 = Another.Criteria2)
...;
}
...
end.
В наследниках можно реализовать свои собственные правила извлечения значений критериев, а можно оставить и родительские.
Сравнение можно реализовать "снаружи". Этот вариант мне лично нравится больше, т.к. позволяет описывать много различных способов сравнения ("больше", "меньше", "подобен", "конгруэнтен"):
Код: Выделить всё
function Equals(One, Another: IComparable): boolean;
Обе схемы позволяют описать асимметричное сравнение, при котором A = B, но B <> A. Например, с некоторой точки зрения Стул можно использовать как Стол, но Стол нельзя использовать как Стул
Всегда лучше абстрагироваться от частностей и работать с obj-интерфейсами, описывающими независимые сущности или независимые наборы характеристик их возможных реализаций. Obj-интерфейсы нужны для получения полиморфизма. Наследование vip-интерфейсов используйте только для того, чтобы копировать и расширять реализацию.