【问题标题】:Delphi: Method 'Create' hides virtual method of base - but it's right thereDelphi:方法“创建”隐藏了基础的虚拟方法 - 但它就在那里
【发布时间】:2012-02-01 20:58:37
【问题描述】:

考虑假设的对象层次结构,从:

TFruit = class(TObject)
public
    constructor Create(Color: TColor); virtual;
end;

及其后代:

TApple = class(TFruit)
public
    constructor Create(); overload; virtual;
    constructor Create(Color: TColor); overload; override; //deprecated. Calls other constructor - maintaining the virtual constructor chain
end;

这里的想法是我重写基类的虚拟构造函数,重载也恰好是虚拟的.

德尔福抱怨:

方法 'Create' 隐藏基本类型 'TFruit' 的虚拟方法

除了它没有隐藏它 - 它就在那里!

  • 覆盖祖先中的虚方法,并且
  • 重载了另一个版本

怎么了?

【问题讨论】:

  • 我得到“方法‘创建’隐藏了基本类型‘TFruit’的虚拟方法”;你真的得到“基本类型'TApple'”吗?
  • @RBA 不完全是,在这种情况下警告是不正确的,尽管您可以使用reintroduce; 来避免它。
  • 这是 Delphi 5 特有的?
  • @EMBarbosa 不,但是当使用旧版本时,您可能想知道这样的事情是否特定于该版本的。 OP 只是提供信息。
  • @NGLN 是的。所以我认为它不需要delphi-5标签?

标签: delphi overloading


【解决方案1】:

两种解决方案:

type
  TFruit = class(TObject)
  public
    constructor Create(Color: TColor); virtual;
  end;

  TApple = class(TFruit)
  public
    constructor Create(); reintroduce; overload;
    constructor Create(Color: TColor); overload; override;
  end;

或者:

type
  TFruit = class(TObject)
  public
    constructor Create; overload; virtual; abstract;
    constructor Create(Color: TColor); overload; virtual;
  end;

  TApple = class(TFruit)
  public
    constructor Create(); override;
    constructor Create(Color: TColor); override; 
  end;

【讨论】:

  • +1。我找不到让 XE2 的编译器满意的 overloadvirtual 和/或 override 的组合。 :)
  • @WarrenP 这种味道来自reintroduce 的其他用途,这经常会破坏继承。
  • @NGLN 在我的情况下,当我试图维护继承时,编译器正在与我作斗争。我可以隐藏祖先并完成它,但这会破坏多态构造函数。
  • 我是唯一一个认为多态构造函数是另一种代码味道的人吗?
  • @WarrenP, TComponent.Create 是一个多态构造函数,它是 Delphi 工作方式的核心。我觉得它很漂亮,我什么都闻不到。
【解决方案2】:

这似乎是一个“先到先得”的问题。 (NGLN 似乎找到了解决方案。)

还有另一种解决方案。您可以使用默认参数:

interface

type
  TFruit=class(TObject)
  public
    constructor Create(Color: TColor); virtual;
  end;

  TApple=class(TFruit)
  public
    constructor Create(Color: TColor = clRed); override;
  end;

implementation

{ TFruit }

constructor TFruit.Create(Color: TColor);
begin
  inherited Create;
end;

{ TApple }

constructor TApple.Create(Color: TColor);
begin
  inherited;
end;

// Test code
var
  AppleOne, AppleTwo: TApple;
begin
  AppleOne := TApple.Create;
  AppleTwo := TApple.Create(clGreen);
end;

【讨论】:

  • +1 创意。但是不需要重新引入,我会使用clDefault。 ;)
  • 谢谢。 :) 你说得对。我认为这是早期试验之一的残余,编译器没有抱怨,所以我没有抓住它。而且我从未见过clDefault 彩色苹果。 ;)
  • 我没有提到它是为了给苹果上色,而是为了坚持问题的目的,即在 TApple 中添加无参数构造函数。显然 OP 认为有没有任何颜色的苹果。 ;) 此外,clDefault 到底是什么颜色?这是苹果的默认颜色,不是吗? (好吧,它实现为黑色,但这只是因为 TColor 只需要一些整数值)。
  • ;) 我从未见过任何有颜色的clDefault 我会选择作为我想吃的苹果。 在我看来,如果你正在创建一个名为Apple 的水果,它应该默认为苹果的典型颜色值(红色、绿色、黄色或金色等)。 :) 我不希望看到苹果在它们变黑之前坐在那里,但这可能只是我自己的偏见。
  • 是的,好吧,这有点花言巧语,苹果样本并没有让我觉得它更好。但肯定 OP 不是在设计水果继承。我提出的一般观点是在谈到默认颜色时使用clDefault。当然,默认参数在某种程度上意味着 default。 ;) 我经常使用clDefault:例如当将颜色属性设置为clDefault 时,颜色会切换回默认状态,并且可以根据组件的其他属性变成除clDefault 之外的任何其他颜色。我现在就停下来...... ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
相关资源
最近更新 更多