2

私は Delphi 2006 を使用しており、TMyClassTest多くのメソッドを持つ複雑な名前のクラスがあります。これらのメソッドのいくつかは、非ビジュアル コンポーネントを作成し、それらのコンポーネントのイベント ハンドラを割り当て、それらのコンポーネントのメソッドを実行します。

また、以下のような同じインターフェースを実装する 2 つのクラスがあります。

TMyClass1 = class(Class1, Interface1)
   ... //procedures from the Interface1
   procedure MyClass1Proc1;
 end;

TMyClass2 = class(Class2, Interface1)
   ... //procedures from the Interface1
   procedure MyClass2Proc1;
   procedure MyClass2Proc2
 end;

TMyClassTest を「継承」するには、TMyClass1 と TMyClass2 も必要です。さらに... Interface1 には (そのメソッドを超えて) MyClassTest のすべてのメソッドが含まれている必要があります。TMyClassTest のすべてのプロシージャを両方のクラス (TMyClass1 と TMyClass2) に実装 (コピー/貼り付けなど) しないようにするにはどうすればよいですか? 同じコードを 3 つの別々の場所に保持したくありません。

Ariochのコメントに基づいて、次のようなソリューションを作成しました。

    type
      IMyInterface = interface
        procedure P1;
        procedure P2;
      end;
      TMyImplClass = class
        procedure P1;
        procedure P2;
      end;
      TMyClass1 = class(Class1, IMyInterface)
        FMyImplClass: TMyImplClass;
        property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
        procedure IMyInterface.P1 = MyP1;
        procedure MyP1;
      end;
      TMyClass2 = class(TInterfacedObject, IMyInterface)
        FMyImplClass: TMyImplClass;
        property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
        procedure P3;
        procedure P4;
      end;
    procedure TMyImplClass.P1;
         // ...
    procedure TMyImplClass.P2;
         // ...
    procedure TMyClass1.MyP1;
         // ...
    procedure TMyClass2.P3;
         // ...
    procedure TMyClass2.P4;
         // ...
    var
      MyClass: TMyClass1;
      MyInterface: IMyInterface;
    begin
      MyClass := TMyClass1.Create;
      MyClass.FMyImplClass := TMyImplClass.Create; //Error !!!! FMyImplClass is a read only    property !!!
      MyInterface := MyClass;
      MyInterface.P1;   // calls TMyClass1.MyP1;
      MyInterface.P2;   // calls TImplClass.P2;
    end;

エラーが発生したため、 andから宣言コンストラクターMyClass.FMyImplClass := TMyImplClass.Create;を作成しようとしましたが、正常に動作しません。作成する他の方法はありますか?FMyImplClassTMyClass1TMyClass2FMyImplClass

今、私はうまくいくと思われる解決策を試しました。いくつかの隠された効果が発生する可能性がありますか?

    type
      IMyInterface = interface
        procedure P1;
        procedure P2;
        procedure CreateFMyImplClass;
      end;
      TMyImplClass = class
        procedure P1;
        procedure P2;
      end;
      TMyClass1 = class(Class1, IMyInterface)
        FMyImplClass: TMyImplClass;
        property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
        procedure IMyInterface.P1 = MyP1;
        procedure MyP1;
        procedure CreateFMyImplClass;
      end;
      TMyClass2 = class(TInterfacedObject, IMyInterface)
        FMyImplClass: TMyImplClass;
        property MyImplClass: TMyImplClass read FMyImplClass implements IMyInterface;
        procedure P3;
        procedure P4;
        procedure CreateFMyImplClass;
      end;
    procedure TMyImplClass.P1;
         // ...
    procedure TMyImplClass.P2;
         // ...
    procedure TMyClass1.MyP1;
         // ...
    procedure TMyClass1.CreateFMyImplClass;
    begin
     FMyImplClass := TMyImplClass.Create;
    end;
    procedure TMyClass2.P3;
         // ...
    procedure TMyClass2.P4;
         // ...
    procedure TMyClass2.CreateFMyImplClass;
    begin
     FMyImplClass := TMyImplClass.Create;
    end;
    var
      MyInterface: IMyInterface;
    begin
      if WantRemote then
         MyInterface := TMyClass1.Create
      else
         MyInterface := TMyClass2.Create;
      MyInterface.CreateFMyImplClass;   // create FMyImplClass ;
      MyInterface.P2;   // calls TImplClass.P2;
    end;
4

1 に答える 1

3

Delphi には、Scala のような特性や Python のような mixin がなく、C++ のような多重継承もサポートされていません。

Class1を作成してからClass2継承できない場合は、おそらくインターフェイスの委任TMyClassTestに依存する必要があります。直接実装するのではなく、代わりにフィールドを追加して、このフィールドに委任します。TMyClassXInterface1TMyClassTestInterface1

したほうがいいと思います

  1. それらの新しい共通関数を何らかのInterface0タイプに移動します
  2. Interface1から継承させるInterface0
  3. TMyClassesBaseCommonTraitクラスを作成し、実装するInterface0
  4. 2 つのサブクラスTMyClass1InternalEngine(TMyClassesBaseCommonTrait)を作成し、TMyClass2InternalEngine(TMyClassesBaseCommonTrait)実装します (さまざまTMyClassXな固有の方法で、残りのInterface1(Interface0)API
  5. タイプ doign real 実装TMyClassXの内部プライベート フィールドをクラスに持つTMyClass2InternalEngine

「デルファイ インターフェイス委任」の Google は、これをトップ リンクとして示しています: Delphi: How delegate interface implementation to child object?

于 2012-12-22T09:59:28.433 に答える