Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you override delegated method implementation?

In Delphi 2007, I am using one class to implement one of the supported interfaces of second class. This is working. The Delphi help states:

By default, using the implements keyword delegates all interface methods. However, you can use methods resolution clauses or declare methods in your class that implement some of the interface methods to override this default behavior.

However, when I declare a method in my second class that has the matching signature of one of the interface methods, it isn't getting called.

I wonder if this is because I'm accessing the class through another interface when I create it.

Below is a test program that demonstrates my problem:

program Project1;

{$APPTYPE CONSOLE}

type
  IInterface1 = interface
  ['{15400E71-A39B-4503-BE58-B6D19409CF90}']
    procedure AProc;
  end;

  IInterface2 = interface
  ['{1E41CDBF-3C80-4E3E-8F27-CB18718E8FA3}']
  end;

  TDelegate = class(TObject)
  protected
    procedure AProc;
  end;

  TMyClass = class(TInterfacedObject, IInterface1, IInterface2)
  strict private
    FDelegate: TDelegate;
    property Delegate: TDelegate read FDelegate implements IInterface1;
  public
    constructor Create;
    destructor Destroy; override;
    procedure AProc;
  end;

procedure TDelegate.AProc;

begin
  writeln('TClassDelegate.AProc');
end;

constructor TMyClass.Create;
begin
  inherited;
  FDelegate := TDelegate.Create;
end;

destructor TMyClass.Destroy;
begin
  FDelegate.Free;
  inherited;
end;

procedure TMyClass.AProc;

begin
  writeln('TMyClass.AProc');
end;

var
  MyObj : IInterface2;

begin
    MyObj := TMyClass.Create;
   (MyObj as IInterface1).AProc;
end.

When I run this I get as output:

TClassDelegate.AProc

What I want is:

TMyClass.AProc

Any help appreciated.

like image 931
Richard A Avatar asked Jan 17 '23 08:01

Richard A


1 Answers

seems you have to redeclare your method in this way:

TMyClass = class(TInterfacedObject, IInterface1, IInterface2)
strict private
  ....
  procedure test();
public
  ....
  procedure  IInterface1.AProc = test;
end;

procedure TMyClass.test;
begin
  writeln('TMyClass.AProc');
end;

so IInterface1.AProc for TMyClass is mapped to Test() (not to FDelegate.AProc) and result is TMyClass.AProc

like image 68
teran Avatar answered Jan 29 '23 11:01

teran