reintroduce在Delphi 中使用关键字的动机是什么?
如果您的子类包含与父类中的虚函数同名的函数,并且未使用override修饰符声明它,则它是编译错误.在这种情况下添加reintroduce修饰符可以修复错误,但我从未理解编译错误的原因.
更新:用一个更简单的例子来解决问题,原来接受的答案没有回答
鉴于以下类及其祖先:
TComputer = class(TObject)
public
constructor Create(Teapot: string='');
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); overload; virtual;
constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
Run Code Online (Sandbox Code Playgroud)
现在TCellPhone有3个构造函数可见:
我该怎么做才能TCellPhone使祖先构造函数(Teapot: string = '')不可见,只留下声明的构造函数:
注:通常简单的行为有一个后代的构造函数隐藏了祖先:
Run Code Online (Sandbox Code Playgroud)TCellPhone = class(TComputer) public constructor Create(Cup: Integer); virtual; end;
- 杯子:整数
如果你想保留祖先构造函数和后代,你可以将后代标记为
overload:Run Code Online (Sandbox Code Playgroud)TCellPhone = class(TComputer) public constructor Create(Cup: Integer); overload; virtual; end;
- 杯子:整数
- 茶壶:string =''
在这个问题的示例代码中,Delphi误解了我的 …
更新:我最初的例子有点复杂.这是一个简单的8行示例,它解释了一个代码块中的所有内容.以下不编译会发出警告:
TComputer = class(TObject)
public
constructor Create(Cup: Integer); virtual;
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer; Teapot: string); virtual;
end;
Run Code Online (Sandbox Code Playgroud)
注意:这个问题是我正在进行的关于Delphi中构造函数的子句的系列问题的第3部分
如何将构造函数添加到现有类?
让我们给出一个假设的例子(即我在SO编辑器中输入的一个例子,它可能编译也可能不编译):
TXHTMLStream = class(TXMLStream)
public
...
end;
Run Code Online (Sandbox Code Playgroud)
进一步假设正常使用TXHTMLStream涉及在可以使用之前执行大量重复代码:
var
xs: TXHTMLStream;
begin
xs := TXHTMLStream.Create(filename);
xs.Encoding := UTF32;
xs.XmlVersion := 1.1;
xs.DocType := 'strict';
xs.PreserveWhitespace := 'true';
...
xs.Save(xhtmlDocument);
Run Code Online (Sandbox Code Playgroud)
假设我想创建一个简化所有样板设置代码的构造函数:
TXHTMLStream = class(TXMLStream)
public
constructor Create(filename: string; Encoding: TEncoding); virtual;
end;
constructor TXHTMLStream.Create(filename: string; Encoding: TEncoding);
begin
inherited Create(filename);
xs.Encoding …Run Code Online (Sandbox Code Playgroud) 今天最近在Stackoverflow上我了解到:
我一直试图弄清楚这一切,所以这是另一个非常具体的问题,支持我处理构造函数的主要问题.
更新:替换了整个问题:
TComputer = class(TObject)
public
constructor Create(Teapot: string='');
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); overload; virtual;
constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
Run Code Online (Sandbox Code Playgroud)
构建TCellPhone时,可以使用3个构造函数:
问题:为什么constructor(Teapot: string='')不被隐藏?
现在我添加了第三个后代:
TComputer = class(TObject)
public
constructor Create(Teapot: string='');
end;
TCellPhone = class(TComputer)
public
constructor Create(Cup: Integer); overload; virtual;
constructor Create(Cup: Integer; Teapot: string); overload; virtual;
end;
TiPhone = class(TCellPhone)
public
constructor Create(Cup: …Run Code Online (Sandbox Code Playgroud) 之后看了伊恩·博伊德的构造一系列问题(1,2,3,4),我知道我还是不太懂的什么东西被隐藏的字面含义.
我知道(纠正我,如果我错了)override唯一的目的是能够具有多态行为,以便运行时可以根据实例的实际类型解析方法 - 而不是声明的类型.请考虑以下代码:
type
TBase = class
procedure Proc1; virtual;
procedure Proc2; virtual;
end;
TChild = class(TBase)
procedure Proc1; override;
procedure Proc2; // <- [DCC Warning]
end;
procedure TBase.Proc1;
begin
Writeln('Base.Proc1');
end;
procedure TBase.Proc2;
begin
Writeln('Base.Proc2');
end;
procedure TChild.Proc1;
begin
inherited Proc1;
Writeln('Child.Proc1');
end;
procedure TChild.Proc2;
begin
inherited Proc2;
Writeln('Child.Proc2');
end;
var
Base: TBase;
begin
Base := TChild.Create;
Base.Proc1;
Writeln;
Base.Proc2;
Base.Free;
Readln;
end.
Run Code Online (Sandbox Code Playgroud)
哪个输出:
Base.Proc1
Child.Proc1 …
我只是想问一个简单的问题 - 我有一个派生自TLabel的类如下:
TMyLabel = class (TLabel)
...
constructor Create(AOwner: TComponent); override;
end;
constructor TMyLabel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{ some code }
end;
Run Code Online (Sandbox Code Playgroud)
现在,Delphi允许我使用和不使用覆盖来编译两个版本.你能解释一下这些差异是什么吗?除了在被覆盖Create()时无法请求我自己的参数.谢谢
编辑:我的意思是 - a virtual和非虚拟基础后代构造函数之间的区别是什么?我总是可以调用继承的构造函数inherited Create(),那有什么意义呢?
如你所知,在c#中初始化对象非常方便快捷
StudentName student2 = new StudentName
{
FirstName = "Craig",
LastName = "Playstead",
};
Run Code Online (Sandbox Code Playgroud)
和
List<MyObject>.Add(new MyObject{a=1,b=2})
Run Code Online (Sandbox Code Playgroud)
可以像这样在Delphi中初始化对象吗?
我正在阅读这篇文章,因为我想了解它的用处,class of [ClassName]并且我已经看到它们声明了一个虚拟构造函数.所以我做了一个测试,你可以在这里看到:
我理解(从那篇文章中)当我在编译时不知道我想要构造的类并且我可以使用它时,虚拟构造函数是有用的class of.在我上面显示的代码中,有什么区别?
如果我将TFirst构造函数声明为虚拟而不覆盖TSecond我会得到警告当然广告我可以通过重新引入或覆盖来删除它.但是不是构造函数自动覆盖(查看左边的代码)?我认为他们是等同的.