我是 Delphi 编码的新手,在尝试重写构造函数时遇到错误,您能否建议我做错了什么,或者我应该做什么才能获得所需的结果。
我想重写框架的构造函数,以便它可以将其包含的标签标题更改为特定文本。
这是代码
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TfrmMesaj = class(TFrame)
Panel1: TPanel;
private
{ Private declarations }
public
{ Public declarations }
constructor Create(name : string); override;
end;
implementation
{$R *.dfm}
{ TfrmMesaj }
{ TfrmMesaj }
constructor TfrmMesaj.Create(name: string);
begin
inherited;
Panel1.Color := clRed;
Panel1.Caption := name;
end;
end.
当我尝试编译时出现以下错误:
[DCC Error] frameMesaj.pas(17): E2037 Declaration of 'Create' differs from previous declaration
[DCC Error] frameMesaj.pas(32): E2008 Incompatible types
我做错了什么以及如何实现我想要的?
最佳答案
Stefan已经解释了为什么你的覆盖不起作用。基本上,每当您重写虚拟方法时,两个方法的签名都必须完全匹配。但是,我强烈反对使用 reintroduce
。我将在这个答案的底部解释原因。 (另请注意,重新引入非常明确不会覆盖祖先方法。它仅隐藏警告该方法隐藏祖先的方法。)
几个更好的选择:
为构造函数使用不同的名称
您不必将构造函数命名为 Create
。例如,您可以添加第二个构造函数: constructor CreateWithCaption(AName: string);
。请注意,我什至没有将此构造函数设为虚拟。仅当您希望方法具有多态性时才将其设为虚拟方法。 (这意味着您希望子类即使从基类调用时也能够更改实现。)
此选项非常类似于 Stefan 建议的重载。
使用工厂方法创建框架
随着系统变得越来越大,将创建某些对象的处理与它们实际执行的工作分开会很有用。这是使用工厂方法完成的,工厂方法的唯一目的是创建准备与系统其余部分交互的其他对象。例如
//I've chosen to demonsrate this on a form, but you could also implement a dedicated factory class
function TMyForm.CreateMessageFrame(ACaption: string): TFrame;
begin
//Note the factory method intends the form to own all frames created.
Result := TfrmMesaj.Create(Self);
//The factory method ensures the frame is "ready"
//This does violate Law of Demeter, but you could easily add a method to the fram to resolve that.
Result.Panel1.Color := clRed;
Result.Panel1.Caption := ACaption;
end;
<小时/>
reintroduce
有什么问题吗?无论如何?
- Reintroduce 仅适用于基类上的方法为 virtual 的情况。
- 仅当打算多态使用时,该方法才应该是虚拟的。
- 这意味着该方法旨在从基类引用中调用,但可能需要采取特殊操作才能在某些子类中正常工作。
由于您的问题是处理重写 TComponent.Create
,它可以很好地通过示例进行说明。
-
constructor TComponent.Create(AOwner: TComponent);
是虚拟,非常具体,因此组件创建的行为是多态的。这样,当组件从 .DFM 文件流式传输时,即使用于创建它们的引用类型为TComponent
,它们也会正确创建。 . - 如果隐藏此构造函数,则在流式传输帧并从 .DFM 创建帧时需要执行的任何特殊操作都不会发生。
- 此外,您的框架的任何子类将无法覆盖
constructor Create(AOwner: TComponent);
因为它是隐藏的。
关于delphi - 覆盖构造错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23806739/