4

这两段代码有什么区别

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;

如果它们是相同的,是否有任何优势或可读性问题。

我猜第二个意味着你不能编写一个实现 IInterface2 的类而不实现 IInterface1,而第一个你可以。

4

4 回答 4

6

如果我们谈论的是用于 Win32 的 Delphi(用于 .NET 的 Delphi 有不同的规则),那么这两个代码片段具有非常不同的效果,并且几乎不等同。

  1. 实现其接口的类必须实现该接口祖先的所有成员,但它不会式实现祖先。因此,尝试将 TMyClass 类型的实例分配给 IInterface1 类型的位置对于第二种情况将失败。
  2. 与前一点相关,如果 IInterface1 和 IInterface2 都具有 GUID,则在第二种情况下,目标类型为 IInterface1 的接口引用的动态转换(使用Supports或' ')将在 TMyClass 实例上失败。as
  3. 接口 IInterface2 在第二种情况下有一个额外的方法,而在第一种情况下没有。
  4. 第二种情况下 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

首先,我假设第二个示例的 IInterface2 声明是一个错字,应该是

IInterface2 = interface(Interface1)

因为从自身继承是荒谬的(即使编译器接受了它)。

而“继承”是回答你问题的关键词。在示例 1 中,这两个接口是完全独立的,您可以毫无问题地实现一个、另一个或两者。在示例 2 中,您是正确的,如果不实现 interface1 就无法实现 interface2,但之所以如此,是因为它使 interface1 成为 interface2的一部分

那么,区别主要在于结构和组织,而不仅仅是可读性。

于 2008-10-02T14:46:18.350 回答
1

假设你的意思

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

我和你的解释一样,第二种形式需要一个实现 Interface2 的类来实现 Interface1,而第一种形式不需要。

于 2008-10-02T14:42:36.517 回答
1

我猜第二个意味着你不能编写一个实现 IInterface2 的类而不实现 IInterface1,而第一个你可以。

那将是技术差异。

哪个更好在很大程度上取决于接口实际上是什么。如果 IInterface2 也不是 IInterface1 存在,它是否有意义?

如果 IInterface1 是“可显示的”而 IInterface2 是“可存储的”,那么第一个选项可能更有意义。如果 IInterface1 是“车辆”而 IInterface2 是“卡车”,那么第二个选项可能更有意义。

于 2008-10-02T14:46:04.417 回答