【问题标题】:Class helper doesn't override ancestor's virtual methods类助手不会覆盖祖先的虚拟方法
【发布时间】:2019-03-13 14:25:22
【问题描述】:

我一直将类助手理解为扩展类或部分类。它们就像原始基类代码的扩展。如果我复制代码的接口部分并将其添加到基类中并为实现也这样做,代码将完全以与助手相同的方式运行。这让我总能理解助手中的多态性,以及为什么它们不能覆盖基类中的方法等。

但我发现这并不完全正确,因为如果是这样,那么为什么他们不允许覆盖基类的祖先-父级的方法?

这是我的意思的一个例子(我只会放标题的代码而没有实现代码):

type
  TAncestor = class
  public 
    procedure Test; virtual;
  end;

  TBase = class(TAncestor)
  public 
  end;

那么为什么下一个代码不正确:

THelper = class helper of TBase
public 
  procedure Test; override;
end;

我的错误是:

在基类中找不到方法“测试”!

【问题讨论】:

  • 助手安装在侧面。他们只是扩展名称空间。要覆盖虚拟方法,您需要子类化。
  • @DavidHeffernan 实际上我是子类,TBase 是 TAncestor 的子类...
  • 你需要继承TBase而不是扩展TBase。或者重写TBase中的方法。

标签: delphi polymorphism delphi-xe3


【解决方案1】:

类助手不能修改原来的类布局。这就是为什么他们不能添加字段(但他们可以添加非虚拟非动态方法,当然)。额外的方法实际上并不是帮助类的一部分,它们只是告诉编译器每次看到该方法时,它应该假装它是原始类的一部分

但是重写虚方法意味着修改帮助类的虚方法表,这也是不可能的。编译器当然可以创建一个新的 VMT(指向代码的指针数组),其中包含覆盖,但是,因为类助手不修改“帮助”实例,它不能简单地替换实例中的 VMT 指针与新的。因此无法使实例引用新的 VMT。

只有一种方法可以覆盖虚拟方法:通过继承。

Documentation 说:

辅助类型可能不声明实例数据,但允许使用类字段。

【讨论】:

  • @ZORRO_BLANCO 完全错误。助手不能添加字段。另外,请考虑两个不同的单元是否为此类提供了帮助程序并可以提供覆盖。会调用哪个方法?
  • 他们不能添加字段,只能添加方法(仍然不能覆盖那些,只能添加 add 方法)。而且您只能同时拥有一个助手,因此这取决于哪个助手的范围最接近。
  • @ZORRO_BLANCO 我对这两个助手的问题非常相关。如果你能做到你所要求的,考虑一下哪个助手会赢?请记住,您可能会在代码中没有可见助手的位置对键入为 TAncestor 的引用进行调用?
  • @ZORRO_BLANCO:不,他们没有。
  • @RudyVelthuis 啊哈,这最后的信息是我猜的关键,我不知道虚拟方法需要一个字段,我从你的回答中不明白,我认为它会是如果您将其添加到答案中会很有帮助:) 再次感谢,请执行我糟糕的英语理解
【解决方案2】:

尝试“类拦截”(ggl it)
这样的东西类似于delphi中的c#“部分类”

type
  TPageControl = class(Vcl.ComCtrls.TPageControl)
....

【讨论】:

  • Na verdade isso se chama "Interposer Class"
猜你喜欢
  • 1970-01-01
  • 2012-06-19
  • 2013-06-18
  • 2019-07-16
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 2011-05-21
  • 1970-01-01
相关资源
最近更新 更多