Delphi:我应该使用重载、重新引入+重载还是none?

Delphi: should I use overload, reintroduce + overload or none?

子类中重写了基类中的虚方法

但是,我需要在子类方法中添加一个新的参数,并且不可能使用"override"声明,因为参数不同。

示例:

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

  TApple = class(TFruit)
  public
    constructor Create(Color: TColor); override; // Error: Declaration of 'Create' differs from previous declaration
  end;

我知道在这种情况下一个好的做法是创建一个具有另一个名称的新方法,但是很多代码都是多余的。这个新参数只会影响几行...

然后我想到用"overload",但是后来我不能和"override"一起使用。所以我问:只用"overload"有什么问题吗? (Delphi 显示警告:方法 'Create' 隐藏基类型 'TFruit' 的虚拟方法)

我还检查了 reintroduce + overload 的使用(以隐藏上面的警告),但我也看到了关于这种做法的不好建议。你怎么看?

最后,如果我不使用其中的 none,只是在子类方法中删除 "override" 并添加新参数怎么办? (这给了我同样的警告)

有人对我在这种情况下应该怎么做以保持良好做法有任何建议吗?

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

  TApple = class(TFruit)
  public
    constructor Create; override;

    // What should I do:
    //  constructor Create(Color: TColor); overload; // Shows a warning
    //  constructor Create(Color: TColor); reintroduce; overload; // Hides the warning
    //  constructor Create(Color: TColor); // Shows a warning
    //  Other solution?
  end;

谢谢!

Delphi 中的构造函数不必命名 Create()。他们可以随心所欲地命名。所以如果你需要引入一个新的参数,而且它只影响几行代码,我建议创建一个全新的构造函数:

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

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

constructor TApple.CreateWithColor(Color: TColor);
begin
  inherited Create;
  // use Color as needed...
end;

您的大部分代码仍然可以调用 TApple.Create(),少数受影响的行可以改为调用 TApple.CreateWithColor()

否则,如果必须保留 Create() 名称,请使用 reintroduce,并为其提供默认参数,以便现有代码仍可编译:

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

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

constructor TApple.Create(Color: TColor);
begin
  inherited Create;
  // use Color as needed...
end;

只要知道无论哪种方式,如果您使用 class of TFruit 元类创建派生对象实例(这是 virtual 构造函数的通常原因),您将无法调用自定义 TApple 构造函数:

type
  TFruit = class(TObject)
  public
    constructor Create; virtual;
  end;
  TFruitClass = class of TFruit;

  TApple = class(TFruit)
  public
    constructor Create(Color: TColor = clNone); reintroduce;
    // constructor CreateWithColor(Color: TColor);
  end;

var
  Fruit: TFruit;
  Cls: TFruitClass;
begin
  Cls := TApple;
  Fruit := Cls.Create; // calls TFruit.Create() since it is not overridden in TApple...
  //...
end;