4

これら2つのコードの違いは何ですか

type
  IInterface1 = interface
    procedure Proc1;
  end;

  IInterface2 = interface
    procedure Proc2;
  end;

  TMyClass = class(TInterfacedObject, IInterface1, IInterface2)
  protected
    procedure Proc1;
    procedure Proc2;
  end;

そして以下:

type
  IInterface1 = interface
    procedure Proc1;
  end;

  IInterface2 = interface(Interface1)
    procedure Proc2;
  end;

  TMyClass = class(TInterfacedObject,  IInterface2)
  protected
    procedure Proc1;
    procedure Proc2;
  end;

それらがまったく同じである場合、どちらにも利点や読みやすさの問題はありますか。

2 番目は、IInterface1 を実装せずに IInterface2 を実装するクラスを作成できないことを意味すると思いますが、最初のクラスでは可能です。

4

4 に答える 4

6

Delphi for Win32 について話している場合、コードの 2 つのスニペットは非常に異なる効果を持ち、ほとんど同等ではありません (Delphi for .NET には異なるルールがあります)。

  1. そのインターフェイスを実装するクラスは、そのインターフェイスの祖先のすべてのメンバーを実装する必要がありますが、祖先を暗黙的に実装するわけではありません。したがって、タイプ TMyClass のインスタンスをタイプ IInterface1 の場所に割り当てようとすると、2 番目のケースでは失敗します。
  2. 前のポイントに関連して、IInterface1 と IInterface2 の両方に GUID がある場合、IInterface1 のターゲット タイプを持つインターフェイス参照の動的キャスト (Supportsまたは ' as' を使用) は、2 番目のケースの TMyClass のインスタンスで失敗します。
  3. インターフェイス IInterface2 には、2 番目のケースでは追加のメソッドがありますが、最初のケースにはありません。
  4. 2 番目のケースの IInterface2 型の値は、IInterface1 型の場所に割り当てることができます。これは最初のケースには当てはまりません。

この例で自分の目で確かめてください:

    type
      A_I1 = interface
      end;

      A_I2 = interface(A_I1)
      end;

      A_Class = class(TInterfacedObject, A_I2)
      end;

    procedure TestA;
    var
      a: A_Class;
      x: A_I1;
    begin
      a := A_Class.Create;
      x := a; // fails!
    end;

    type
      B_I1 = interface
      end;

      B_I2 = interface
      end;

      B_Class = class(TInterfacedObject, B_I1, B_I2)
      end;

    procedure TestB;
    var
      a: B_Class;
      x: B_I1;
    begin
      a := B_Class.Create;
      x := a; // succeeds!
    end;

    begin
      TestA;
      TestB;
    end.
于 2008-10-02T19:32:25.727 に答える
4

まず、2 番目の例の IInterface2 の宣言はタイプミスであり、

IInterface2 = interface(Interface1)

それ自体からの継承は無意味だからです (たとえコンパイラがそれを受け入れたとしても)。

そして、「継承」はあなたの質問に答えるためのキーワードです。例 1 では、2 つのインターフェースは完全に独立しており、一方、他方、または両方を問題なく実装できます。例 2 では、interface1 を実装せずに interface2 を実装できないことは正しいですが、その理由は、interface1 を interface2の一部にするためです。

したがって、違いは主に構造的および組織的であり、読みやすさだけではありません。

于 2008-10-02T14:46:18.350 に答える
1

あなたが意味したと仮定して

...
IInterface2 = interface(Interface1)
...

私はそれをあなたと同じように解釈します。2番目の形式はInterface1を実装するためにInterface2を実装するクラスを必要としますが、最初の形式はそうではありません。

于 2008-10-02T14:42:36.517 に答える
1

2つ目は、IInterface1を実装せずにIInterface2を実装するクラスを作成できないことを意味しますが、1つ目は作成できます。

それが技術的な違いになります。

どちらが優れているかは、インターフェイスが実際に何であるかに大きく依存します。IInterface2がIInterface1でなくても存在することは、これまでに意味がありますか?

IInterface1が「表示可能」で、IInterface2が「保存可能」である場合、最初のオプションの方がおそらく理にかなっています。IInterface1が「車両」で、IInterface2が「トラック」の場合、2番目のオプションの方がおそらくはるかに理にかなっています。

于 2008-10-02T14:46:04.417 に答える