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

Rob*_*ter 3 delphi delphi-xe

在子类中有一个在子类中重写的虚方法.

但是,我需要在子类方法中添加一个新参数,因为参数不同,所以不可能使用"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;
Run Code Online (Sandbox Code Playgroud)

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

然后我想到使用"重载",但后来我不能一起使用"覆盖".所以我问:只有使用"过载"有什么问题吗?(Delphi显示警告:方法'创建'隐藏基本类型'TFruit'的虚拟方法)

我还检查了使用重新引入+重载(隐藏上面的警告),但我也看到了关于这种做法的错误建议.你怎么看?

最后,如果我不使用它们,只是删除子类方法中的"覆盖"并添加新的参数?(这给了我同样的警告)

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

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;
Run Code Online (Sandbox Code Playgroud)

谢谢!

Rem*_*eau 12

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;
Run Code Online (Sandbox Code Playgroud)

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

否则,reintroduce如果必须维护Create()名称,并使用默认参数,则使用现有代码仍将编译:

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;
Run Code Online (Sandbox Code Playgroud)

只要知道这两种方式,如果你使用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;
Run Code Online (Sandbox Code Playgroud)