Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Method-Resolution Clause bei Interface-Vererbung (https://www.delphipraxis.net/201679-method-resolution-clause-bei-interface-vererbung.html)

Der schöne Günther 15. Aug 2019 11:20

Delphi-Version: 10 Seattle

Method-Resolution Clause bei Interface-Vererbung
 
Ich möchte dass eine Klasse zwei Interfaces implementiert, und ein Interface ist abgeleitet vom ersten und "verdeckt" eine Methode.

Sieht so aus:
Delphi-Quellcode:
type
   IMyInterface = interface
   ['{521683FE-4DF8-43E5-8575-420FA539CA0A}']
      function getNumber(): Integer;
   end;

   IMyInterfaceEx = interface(IMyInterface)
   ['{06555A86-3DCE-4DC0-84EE-3419B7164F5C}']
      function getNumber(): Single;
   end;

   TMyObject = class(
      TInterfacedObject,
      IMyInterface,
      IMyInterfaceEx
   )
      function IMyInterface.getNumber = IMyInterface_getNumber;
      function IMyInterface_getNumber(): Integer;

      function IMyInterfaceEx_getNumber(): Single;
      function IMyInterfaceEx.getNumber = IMyInterfaceEx_getNumber;
   end;
Ich bekomme in der Zeile
Delphi-Quellcode:
TMyObject = class
leider folgenden Fehler:
Code:
[dcc32 Fehler] Project8.dpr(22): E2291 Implementierung der Interface-Methode IMyInterface.getNumber fehlt
Mache ich was falsch oder will der Compiler einfach nicht? Wenn ja, warum will er nicht?


Link: Doku -> Implementing Interfaces -> Method Resolution clause

Der schöne Günther 15. Aug 2019 11:25

AW: Method-Resolution Clause bei Interface-Vererbung
 
Notfalls ginge es wohl auch so, ich glaube das wäre sogar deutlich besser ohne Interface-Vererbung.

Delphi-Quellcode:
type
   IMyInterface<T> = interface
   ['{521683FE-4DF8-43E5-8575-420FA539CA0A}']
      function getNumber(): T;
   end;

   TMyObject = class(
      TInterfacedObject,
      IMyInterface<Integer>,
      IMyInterface<Single>
   )
      function IMyInterface<Integer>.getNumber = IMyInterface_Integer_getNumber;
      function IMyInterface_Integer_getNumber(): Integer; virtual; abstract;

      function IMyInterface<Single>.getNumber = IMyInterface_Single_getNumber;
      function IMyInterface_Single_getNumber(): Single; virtual; abstract;
   end;

Schokohase 15. Aug 2019 11:36

AW: Method-Resolution Clause bei Interface-Vererbung
 
Dein
Delphi-Quellcode:
IMyInterfaceEx
hat durch die Vererbung jetzt 2 Methoden mit dem Namen
Delphi-Quellcode:
getNumber
. Das soll so sein?

Das ist auf jeden Fall das, was dem Compiler zu schaffen macht.

Such dazu mal nach
Delphi-Quellcode:
IEnumerable
vs.
Delphi-Quellcode:
IEnumerable<T>
. Da hast du das gleiche Problem.

Das hier geht ohne Probleme
Delphi-Quellcode:
type
  IMyInterface = interface
    ['{C67ABDD4-94F0-477D-92FE-A1EC7E790153}']
    function GetNumber(): Integer;
  end;

  IMyInterfaceEx = interface
    ['{4675F531-90C2-48D2-85EB-21EA1A6E063B}']
    function GetNumber(): Single;
  end;

  TMyObject = class(TInterfacedObject, IMyInterface, IMyInterfaceEx)
  private
    function GetIntegerNumber(): Integer;
    function IMyInterface.GetNumber = GetIntegerNumber;

    function GetSingleNumber(): Single;
    function IMyInterfaceEx.GetNumber = GetSingleNumber;
  end;

Stevie 15. Aug 2019 11:40

AW: Method-Resolution Clause bei Interface-Vererbung
 
Gleichnamige Methoden können bei vererbten Interfaces nicht richtig aufgelöst werden mit Method Resolution Clause.

IMyInterfaceEx hat ja 2 Methoden namens getNumber, aber du delegierst nur die von IMyInterface und eine von IMyInterfaceEx (die, die Single zurückliefert).
Nun fehlt noch die getNumber Methode aus IMyInterface, die im IMyInterfaceEx drin steht - da interesiert ihn nicht, dass du IMyInterface.getNumber delegiert hast.

Mein Ansatz in solchen Fällen ist Vererbung der implementierenden Klasse:

Delphi-Quellcode:
   TMyObject = class(
      TInterfacedObject,
      IMyInterface
   )
      function getNumber(): Integer;
   end;

   TMyObjectEx = class(
      TMyObject,
      IMyInterfaceEx
   )
      function IMyInterfaceEx_getNumber(): Single;
      function IMyInterfaceEx.getNumber = IMyInterfaceEx_getNumber;
   end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz