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 =
(IAmYourGrandfather)
'{CAA92E1E-FA55-46BC-8660-51B26AD24D8D}'
SayFatherWisdom;
TSon =
class
(TInterfacedObject, IAmYourFather)
public
TSon2 =
(TInterfacedObject, IAmYourGrandfather, IAmYourFather)
{ TSon }
TSon
.
begin
WriteLn
(
'TSon: Wisdom of father'
);
'TSon: Wisdom of grandfather'
{ TSon2 }
TSon2
'TSon2: Wisdom of father'
'TSon2: Wisdom of grandfather'
var
Son, Son2: IAmYourFather;
Son := TSon
Create;
Son
// Here's the quirk
if
Supports(Son, IAmYourGrandfather)
then
// Son does not support the IAmYourGrandfather interface
Supports(Son, IAmYourFather)
Son2 := TSon2
Supports(Son2, IAmYourGrandfather)
Son2
Supports(Son2, IAmYourFather)
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.