delphi - 当一个类实现了后代接口(interface)时,为什么它不自动算作实现了基接口(interface)?

标签 delphi interface delphi-2010

无法编译的原因是什么?

type
  IInterfaceA = interface ['{44F93616-0161-4912-9D63-3E8AA140CA0D}']
    procedure DoA;
  end;

  IInterfaceB = interface(IInterfaceA) ['{80CB6D35-E12F-462A-AAA9-E7C0F6FE0982}']
    procedure DoB;
  end;

  TImplementsAB = class(TSingletonImplementation, IInterfaceB)
    procedure DoA;
    procedure DoB;
  end;

var
  ImplementsAB: TImplementsAB;
  InterfaceA: IInterfaceA;
  InterfaceB: IInterfaceB;
begin
  ImplementsAB := TImplementsAB.Create;
  InterfaceA := ImplementsAB; >> incompatible types
  ...
end

相反,这就是我让它工作的方式:

InterfaceA := ImplementsAB as InterfaceB;

InterfaceA := InterfaceB;

我的意思是,如果 IInterfaceB 继承自 IInterfaceA 并且 TImplementsAB 实现 IInterfaceB,那么也实现 IInterfaceA 并保持类型兼容是不合逻辑的吗?

最佳答案

这是因为早期的 OLE/COM 有一个错误,Borland 决定与其兼容。这篇文章提到了这一点:New Delphi language feature: Multiple inheritance for interfaces in Delphi for .NET 。解决方案是在类中显式列出所有祖先接口(interface),如 Mikael 所写。

链接文章中的一些引用:

The problem was in COM itself. To load a module, COM would load the DLL, GetProcAddress on a well-known entry point that was supposed to be exported from the DLL, call the DLL function to obtain an IUnknown interface, and then QueryInterface for IClassFactory. The problem was, when Microsoft added support for IClassFactory2, they added the QueryInterface for IClassFactory2 after the existing code that queried for IClassFactory. IClassFactory2 would only be requested if the query for IClassFactory failed.

Thus, COM would never request IClassFactory2 on any COM server that implemented both IClassFactory2 and IClassFactory.

This bug existed in COM for a long time. Microsoft said that they couldn't fix the COM loader with an OS service pack because both Word and Excel (at the time) relied on the buggy behavior. Regardless of whether it's fixed in the latest releases of COM or not, Borland has to provide some way to preserve this behavior in Win32 Delphi for the forseeable future. Suddenly adding all ancestors into an implementing class that weren't there before is very likely to break existing code that unintentionally falls into the same pattern as the COM loader.

关于delphi - 当一个类实现了后代接口(interface)时,为什么它不自动算作实现了基接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8467945/

相关文章:

delphi - 如何将正 float 向上舍入到下一个整数?

Delphi,FastMM - block 在被释放后已被修改 - 需要帮助解释此 FastMM 报告

c# - 与具有相同名称和不同返回类型的成员接口(interface)

android - Delphi XE7 Firemonkey Android 5.1.1 应用程序在三星 Galaxy S7 上仅使用 TEdit 就崩溃

c# - 通过参数的父类(super class)实现接口(interface)

.net - 接口(interface)编程

delphi - 如何使过程更改变量参数的值?

delphi - 在 SQL 中使用参数时,字符串转换错误

delphi - "var"和 "out"参数有什么区别?

delphi - Delphi ITE:什么时候可以更改资源ID?