Calling methods of a legacy interface class and another ancestor

I have a problem with implementing a relationship between some classes. I got three different classes that performed in three different forms. All these classes speak the same language, so they are inherited from the same class TAncestorServer. Let's call his descendants TForm1Server, TForm2Serverand TForm3Server. TAncestorServercontains an abstract method called Function1, therefore TForm1, TForm2and TForm3can easily call it through their own classes inherited from it, they have access to classes through a property with a name Server. But the problem is called in another form TForm4! It is very similar to other forms, but is not so independent. He works with TForm2Serveror TForm3Server. Still not a problem, but imagine another method, for example Function2, which is declared inTForm2Serverand TForm3Server, TForm4. I can go like this:

if Server is TForm2Server then
   TForm2Server(Server).Function2
else if Server is TForm3Server then
  TForm3Server(Server).Function2;

But it can turn into an endless if-else clause! So I thought that something like multiple inheritance might help here. I declared an interface called IForm4Serverthat contains Function2. Therefore, TForm2Serverthey TForm3Serverare inherited both from TAncestorServerand from IForm4Server. I thought something like this might work:

If Server is IForm4Server then
  IForm4Server(Server).Function2;

But the compiler does not think so, he says that this is not a valid type, because TAncestorServernot IForm4Serverthat is absolutely correct. TForm1Serverhas no idea about implementation Function2and should leave it blank. I can not announce TForm4.Serverhow IForm4Servertoo, because Function1is a huge number of methods and properties, but I still can not use the type IForm4Serverto TAncestorServer.

TForm4, GeneralServer: TAncestorServer Form4Server: IForm4Server, TForm2Server TForm3Server, . ? ?

+5
1

- , , .

:

  • ( ) . , - .
  • . GUID .
  • , .
  • :

, , . :

:

type
  TServerForm = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
    procedure Method1; virtual;
  end;

:

type
  IMyInterface = interface
  ['{B7102C7E-F7F6-492A-982A-4C55CB1065B7}']
    procedure Method2;
  end;

:

TServerForm

type
  TServerForm3 = class(TServerForm, IMyInterface)
  public
    procedure Method1; override;
    procedure Method2;
  end;

TServerForm

type
  TServerForm4 = class(TServerForm)
  public
    procedure Method1; override;
  end;

TForm

type
  TNoServerForm = class(TForm, IMyInterface)
  public
    procedure Method2;
  end;

, OnClick ( ):

:

procedure TForm6.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Screen.FormCount - 1 do
  begin
    if (Screen.Forms[I] is TServerForm) then
      TServerForm(Screen.Forms[I]).Method1;
  end;
end;

, :

procedure TForm6.Button2Click(Sender: TObject);
var
  I: Integer;
  Intf: IMyInterface;
begin
  for I := 0 to Screen.FormCount - 1 do
  begin
    if Supports(Screen.Forms[I], IMyInterface, Intf) then
      Intf.Method2;
  end;
end;

, :

procedure TServerForm3.Method2;
begin
  ShowMessage(ClassName + '.Method2');
end;
+6

All Articles