Навеяно это темой:
viewtopic.php?f=127&t=4940Как вам такое извращение?
Код:
MODULE TestInterface;
IMPORT Log := StdLog;
TYPE
Object* = POINTER TO ABSTRACT RECORD END; (* предок всех объектов *)
Interface* = ABSTRACT RECORD END; (* предок всех интерфейсов *)
Printable* = RECORD (Interface) (* объявили некий интерфейс *)
print: PROCEDURE (this: Object);
END;
T0 = POINTER TO RECORD (Object) (* объявили некий объект *)
name: ARRAY 256 OF CHAR;
END;
PROCEDURE (this: Object) With* (VAR msg: Interface): BOOLEAN, NEW, ABSTRACT; (* метод, проверяющий наличие интерфейса и выполняющий инициализацию оного для конкретного объекта *)
PROCEDURE Print* (this: Object); (* реализация метода интерфейса для конкретного объекта *)
BEGIN
WITH this: T0 DO
Log.String(this.name);
END;
END Print;
PROCEDURE (this: T0) With* (VAR iface: Interface): BOOLEAN; (* поддержка интерфейсов в конкретном объекте *)
BEGIN
WITH iface: Printable DO
iface.print := Print;
RETURN TRUE;
ELSE
RETURN FALSE;
END;
END With;
PROCEDURE Do*;
VAR
x: T0;
printable: Printable;
BEGIN
NEW(x);
x.name := "T0";
IF x.With(printable) THEN (* если объект поддерживает интерфейс то вызываем метод интерфейса *)
printable.print(x);
END;
END Do;
END TestInterface.Do
Все это, конечно, надо в три разных модуля раскидать, но мне было лень
ps Сделать можно как полностью на методах, так и полностью на процедурных типах