Несколько совершенно разных классов могут содержать реализацию одного и того же интерфейса. С объектами таких классов можно работать так, будто у них есть общий базовый класс. Интерфейс выступает аналогом общего базового класса.
Рассмотрим пример. Представьте, что есть два класса: TTextReader и TIteratableStringList:
type TTextReader = class(TInterfacedObject, ITextReader, IStringIterator) ... end; TIteratableStringList = class(TStringList, IStringIterator) ... end; |
Схематично полученную иерархию классов можно представить так (рисунок 6.2):

Рисунок 6.2.
Иерархия классов, реализующих интерфейсы. Сплошными линиями
отмечено наследование классов, а пунктирными линиями -
реализация интерфейсов классами.
Объекты классов TTextReader и TIteratableStringList несовместимы между собой. Тем не менее, они совместимы с переменными типа IStringIterator. Это значит, что если есть процедура:
procedure LoadStrings(Iterator: IStringIterator);
|
то вы можете передавать ей объекты обоих упомянутых классов в качестве аргумента:
var ReaderObj: TTextReader; StringsObj: TIteratableStringList; begin ... LoadStrings(ReaderObj); // Все правильно LoadStrings(StringsObj); // Все правильно ... end; |