delphi – 覆盖构造错误
我是Delphi编码的新手,在尝试覆盖构造函数时遇到错误,你能告诉我我做错了什么或者我应该做些什么来达到预期的结果.
我想覆盖一个框架的构造函数,以便它可以将标签的Caption包含在特定文本中. 这是代码 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解释了为什么你的覆盖不起作用.基本上,无论何时覆盖虚方法,两种方法的签名必须完全匹配.但是,我强烈反对使用重新引入.我将在这个答案的底部解释为什么. (请注意,重新引入非常具体,不会覆盖祖先方法.它只隐藏该方法隐藏祖先方法的警告.)
几个更好的选择: 为构造函数使用不同的名称 您不必为构造函数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; 重新引入有什么问题? >重新引入仅适用于基类上的方法是虚拟的. 由于您的问题涉及覆盖TComponent.Create,因此通过示例的方式可以很好地说明. >构造函数TComponent.Create(AOwner:TComponent);是非常具体的虚拟,因此组件创建的行为是多态的.这样,当从.DFM文件流式传输组件时,即使用于创建它们的引用是TComponent类型,也会正确创建它们.>如果隐藏此构造函数,则在从.DFM流式传输和创建帧时需要执行的任何特殊操作都不会发生.>此外,您帧的任何子类都无法覆盖构造函数Create(AOwner:TComponent);因为它是隐藏的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |