在子类中有一个在子类中重写的虚方法。
但是,我需要在子类方法中添加一个新参数,并且不可能使用“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;
我知道在这种情况下的一个好习惯是使用另一个名称创建一个新方法,但是很多代码都是多余的。这个新参数只会影响几行...
然后我想到使用“重载”,但后来我不能一起使用“覆盖”。所以我问:只有使用“过载”有什么问题吗? (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;
谢谢!
答案 0 :(得分: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;
您的大多数代码仍然可以拨打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;
只要知道,无论哪种方式,如果您使用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;