About the author
The following is a description of a Delphi interface artifact that has never been officially documented. Let me explain this in terms of code:
IAmYourGrandfather = interface ['{3CEE2618-E325-4387-A56A-7A7F7FB89259}'] procedure SayGrandfatherWisdom; end; IAmYourFather = interface(IAmYourGrandfather) ['{CAA92E1E-FA55-46BC-8660-51B26AD24D8D}'] procedure SayFatherWisdom; end; TSon = class(TInterfacedObject, IAmYourFather) public procedure SayFatherWisdom; procedure SayGrandfatherWisdom; end; TSon2 = class(TInterfacedObject, IAmYourGrandfather, IAmYourFather) public procedure SayFatherWisdom; procedure SayGrandfatherWisdom; end; { TSon } procedure TSon.SayFatherWisdom; begin WriteLn('TSon: Wisdom of father'); end; procedure TSon.SayGrandfatherWisdom; begin WriteLn('TSon: Wisdom of grandfather'); end; { TSon2 } procedure TSon2.SayFatherWisdom; begin WriteLn('TSon2: Wisdom of father'); end; procedure TSon2.SayGrandfatherWisdom; begin WriteLn('TSon2: Wisdom of grandfather'); end; var Son, Son2: IAmYourFather; begin Son := TSon.Create; Son.SayFatherWisdom; Son.SayGrandfatherWisdom; // Here's the quirk if Supports(Son, IAmYourGrandfather) then // Son does not support the IAmYourGrandfather interface Son.SayGrandfatherWisdom; if Supports(Son, IAmYourFather) then Son.SayFatherWisdom; Son2 := TSon2.Create; if Supports(Son2, IAmYourGrandfather) then Son2.SayGrandfatherWisdom; if Supports(Son2, IAmYourFather) then Son2.SayFatherWisdom; end.
There are 2 interfaces declared, IAmYourGrandfather and IAmYourFather. IAmYourFather inherits from IAmYourGrandfather. TSon implements the IAmYourFather interface, but since the IAmYourFather interface descends from the IAmYourGrandfather interface, a class implementing the IAmYourFather interface inherits the obligation to implement the SayFatherWisdom and SayGrandfatherWisdom methods. However, it is important to note that due to a compiler design decision, the class implementing an interface doesn't advertise that it implements the ancestor interface, unless the class directly implements the ancestor interface.
So, as you see above, what this means is that while TSon and TSon2 both implements the methods declared in the interfaces, only TSon2 supports the IAmYourGrandfather interface, since TSon2 explicitly list it in the class declaration.
A method pointer is now the same as a global procedure, ie, procedure of object = procedure.