我想了解
- 虚拟的
- 覆盖
- 超载
- 重新引入
当应用于对象构造函数时。每次我随机添加关键字直到编译器关闭 - 并且(在使用 Delphi 开发 12 年后)我宁愿知道我在做什么,而不是随机尝试。
给定一组假设的对象:
TComputer = class(TObject)
public
constructor Create(Cup: Integer); virtual;
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string); virtual;
end;
TiPhone = class(TCellPhone)
public
constructor Create(Cup: Integer); override;
constructor Create(Cup: Integer; Teapot: string); override;
end;
我希望他们的行为方式从声明中可能很明显,但是:
TComputer
有简单的构造函数,后代可以覆盖它TCellPhone
有一个备用构造函数,后代可以覆盖它TiPhone
覆盖两个构造函数,调用每个构造函数的继承版本
现在该代码无法编译。我想了解为什么它不起作用。我也想了解重写构造函数的正确方法。或者也许你永远无法覆盖构造函数?或者也许重写构造函数是完全可以接受的?也许你永远不应该有多个构造函数,也许拥有多个构造函数是完全可以接受的。
我想了解原因。修复它就很明显了。
也可以看看
编辑:我也希望对virtual
, override
, overload
,的顺序进行一些推理reintroduce
。因为在尝试所有关键字组合时,组合的数量会爆炸式增长:
- 虚拟的; 超载;
- 虚拟的; 覆盖;
- 覆盖;超载;
- 覆盖;虚拟的;
- 虚拟的; 覆盖;超载;
- 虚拟的; 超载; 覆盖;
- 超载; 虚拟的; 覆盖;
- 覆盖;虚拟的; 超载;
- 覆盖;超载; 虚拟的;
- 超载; 覆盖;虚拟的;
- ETC
编辑2:我想我们应该从“给定的对象层次结构是否可能? ”如果不是,为什么不呢?例如,拥有来自祖先的构造函数是根本不正确的吗?
TComputer = class(TObject)
public
constructor Create(Cup: Integer); virtual;
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string); virtual;
end;
我希望TCellPhone
现在有两个构造函数。但我无法在 Delphi 中找到关键字组合,使其认为这是一件有效的事情。我认为我可以在这里有两个构造函数从根本上是错误的TCellPhone
吗?
注意:这条线以下的所有内容并不是回答问题所必需的——但它确实有助于解释我的想法。也许您可以根据我的思维过程看到,我遗漏了哪些让一切变得清晰的基本部分。
现在这些声明无法编译:
//Method Create hides virtual method of base type TComputer:
TCellPhone = class(TComputer)
constructor Create(Cup: Integer; Teapot: string); virtual;
//Method Create hides virtual method of base type TCellPhone:
TiPhone = class(TCellPhone)
public
constructor Create(Cup: Integer); override;
constructor Create(Cup: Integer; Teapot: string); overload; <--------
end;
所以首先我会尝试修复TCellPhone
。我将从随机添加overload
关键字开始(我知道我不想要reintroduce
,因为这会隐藏另一个我不想要的构造函数):
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string); virtual; overload;
end;
但这失败了:Field definition not allowed after methods or properties
.
我从经验中知道,即使我在方法或属性之后没有字段,如果我颠倒virtual
andoverload
关键字的顺序:Delphi 会闭嘴:
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
但我仍然得到错误:
方法“创建”隐藏基本类型“TComputer”的虚拟方法
所以我尝试删除这两个关键字:
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string);
end;
但我仍然得到错误:
方法“创建”隐藏基本类型“TComputer”的虚拟方法
所以我辞职现在尝试reintroduce
:
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string); reintroduce;
end;
现在 TCellPhone 编译了,但它让 TiPhone 的情况变得更糟:
TiPhone = class(TCellPhone)
public
constructor Create(Cup: Integer); override; <-----cannot override a static method
constructor Create(Cup: Integer; Teapot: string); override; <-----cannot override a static method
end;
两者都抱怨我无法覆盖它们,所以我删除了override
关键字:
TiPhone = class(TCellPhone)
public
constructor Create(Cup: Integer);
constructor Create(Cup: Integer; Teapot: string);
end;
但是现在第二次创建说它必须标记为重载,我这样做(实际上我会将两者都标记为重载,因为我知道如果我不这样做会发生什么):
TiPhone = class(TCellPhone)
public
constructor Create(Cup: Integer); overload;
constructor Create(Cup: Integer; Teapot: string); overload;
end;
该部分的一切都很好interface
。不幸的是,我的实现不起作用。我的 TiPhone 单参数构造函数不能调用继承的构造函数:
constructor TiPhone.Create(Cup: Integer);
begin
inherited Create(Cup); <---- Not enough actual parameters
end;