1

I have to write some interfaces that will be used to implement a number of classes. Some of them will have a "basic" behaviour, others whill have some "advanced" features.
I think the best way is to declare a "basic" interface and an "advanced" child interface.
I'm also tryng to keep a loose coupling between objects and interfaces.

Now I'm running into this problem:
When I create an "Advanced" object (implementing the Child interface), I expect it also implements the Parent interface, but neither "getInterface" nor "Supports" seem to agree with me.

Here is a sample code:

type
  IParent = interface
    ['{684895A1-66A5-4E9F-A509-FCF739F3F227}']
    function ParentFunction: String;
  end;

  IChild = interface(IParent)
    ['{B785591A-E816-4D90-BA01-1FFF865D312A}']
    function ChildFunction: String;
  end;

  TMyClass = class(TInterfacedObject, IChild)
  public
    function ParentFunction: String;
    function ChildFunction: String;
  end;

function TMyClass.ChildFunction: String;
begin
  Result := 'ChildFunction';
end;

function TMyClass.ParentFunction: String;
begin
  Result := 'ParentFunction';
end;

var
  Obj: TMyClass;
  ParentObj: IParent;
  ChildObj: IChild;
begin

  Obj := TMyClass.Create;
  ChildObj := Obj;
  WriteLn(Format('%s as IChild: %s', [Obj.ClassName, ChildObj.ChildFunction]));
  WriteLn(Format('%s as IChild: %s', [Obj.ClassName, ChildObj.ParentFunction]));

  if (Obj.GetInterface(IParent, ParentObj)) then
    WriteLn(Format('GetInterface: %s as IParent: %s', [Obj.ClassName, ParentObj.ParentFunction]))
  else
    WriteLn(Format('GetInterface: %s DOES NOT implement IParent', [Obj.ClassName])); // <-- Why?

  ParentObj := ChildObj;
  WriteLn(Format('%s as IParent: %s', [Obj.ClassName, ParentObj.ParentFunction]));

  if (Supports(Obj, IParent)) then
    WriteLn(Format('Supports: %s Supports IParent', [Obj.ClassName]))
  else
    WriteLn(Format('Supports: %s DOES NOT Support IParent', [Obj.ClassName]));   // <-- Why?

end.

and here is the result:

TMyClass as IChild: ChildFunction
TMyClass as IChild: ParentFunction
GetInterface: TMyClass DOES NOT implement IParent
TMyClass as IParent: ParentFunction
Supports: TMyClass DOES NOT Support IParent

How can I, for example, test if an object implements IParent OR A DESCENDANT of it?

Thank you

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
yankee
  • 509
  • 2
  • 9
  • 18
  • You **must** implement the interface if you want to support it, because each implementing class can implement the interface in a different way. Just have a look at http://pastebin.com/PkQidhFc – Sir Rufo Nov 18 '14 at 10:32

1 Answers1

2

The reason why TMyClass doesn't support IParent is because you didn't say it should do so. That is just as designed. If you want TMyClass to support IParent, just say so in the declaration:

TMyClass = class(TInterfacedObject, IParent, IChild)
Uwe Raabe
  • 45,288
  • 3
  • 82
  • 130