Delphi:如何向后代添加不同的构造函数? [英] Delphi: How to add a different constructor to a descendant?

查看:184
本文介绍了Delphi:如何向后代添加不同的构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:我原来的例子很复杂。这里有一个简单的8行示例,解释一个代码块中的所有内容。以下不会编译发出警告:

  TComputer = class(TObject)
public
constructor Create(Cup:Integer);虚拟;
end;

TCellPhone = class(TComputer)
public
构造函数Create(Cup:Integer; Teapot:string);虚拟;
end;

注意:这个问题是我正在进行的一系列问题的第3部分Delphi中构造函数的细节



原始问题



如何向现有类添加构造函数?



让我们给出一个假设的例子(例如,我在SO编辑器中输入的一个例子,因此它可能或可能无法编译):

  TXHTMLStream = class(TXMLStream)
public
...
end;进一步假设正常使用 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);

假设我想创建一个简化所有样板设置代码的构造函数:

  TXHTMLStream = class(TXMLStream)
public
构造函数Create(filename:string; Encoding:TEncoding);虚拟;
end;

构造函数TXHTMLStream.Create(filename:string; Encoding:TEncoding);
begin
inherited Create(filename);
xs.Encoding:= Encoding;
xs.XmlVersion:= 1.1;
xs.DocType:='strict';
xs.PreserveWhitespace:= True;
...
end;

这简化了对象的使用:

  var 
xs:TXHTMLStream;
begin
xs:= TXHTMLStream.Create(filename,UTF32);
xs.Save(xhtmlDocument);

除了现在Delphi抱怨我的新构造函数隐藏了旧的构造函数。


方法创建隐藏基本类型TXMLStream的虚拟方法


我当然没有 隐藏祖先create - i



如何将一个构造函数(具有不同签名)添加到后代类,同时保留祖先构造函数,

我的直接反应是使用 overload 关键字,如:

  TCellPhone = class(TComputer)
public
constructor Create(Cup:Integer;茶壶:串);再引入超载;虚拟;
end;

编辑:感谢Ian的编辑,我的答案。我想认为我是勇敢的,所以我将提供一个更完整的例子:

 程序Project1; 

{$ APPTYPE CONSOLE}

使用
SysUtils;

type

TComputer = class(TObject)
public
构造函数Create(Cup:Integer);虚拟;
end;

TCellPhone = class(TComputer)
public
构造函数Create(Cup:Integer; Teapot:string);再引入超载;虚拟;
end;

{TComputer}

构造函数TComputer.Create(Cup:Integer);
begin
writeln('constructed computer:cup =',Cup);
end;

{TCellPhone}

构造函数TCellPhone.Create(Cup:Integer; Teapot:string);
begin
inherited创建(Cup);
writeln('constructed cellphone:Teapot =',Teapot);
end;

var
C1,C2,C3:TComputer;

begin
C1:= TComputer.Create(1);
Writeln;
C2:= TCellPhone.Create(2);
Writeln;
C3:= TCellPhone.Create(3,'kettle');
Readln;
end。

,结果是:

 建造的电脑:cup = 1 

建造的电脑:cup = 2

建造的电脑:cup = 3
手机:茶壶= kettle


Update: The example i originally had was kind of complex. Here's a simple 8 line example that explains everything in one code block. The following does not compile gives a warning:

TComputer = class(TObject)
public
    constructor Create(Cup: Integer); virtual;
end;

TCellPhone = class(TComputer)
public
    constructor Create(Cup: Integer; Teapot: string); virtual;
end;

Note: This question is part 3 in my ongoing series of questions about the subtlties of constructors in Delphi

Original question

How can i add a constructor to an existing class?

Let's give an hypothetical example (i.e. one that i'm typing up in here in the SO editor so it may or may not compile):

TXHTMLStream = class(TXMLStream)
public
   ...
end;

Further assume that the normal use of TXHTMLStream involved performing a lot of repeated code before it can be used:

var
   xs: TXHTMLStream;
begin
   xs := TXHTMLStream.Create(filename);
   xs.Encoding := UTF32;
   xs.XmlVersion := 1.1;
   xs.DocType := 'strict';
   xs.PreserveWhitespace := 'true';
   ...

   xs.Save(xhtmlDocument);

Assume that i want to create a constructor that simplifies all that boilerplate setup code:

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 := Encoding;
   xs.XmlVersion := 1.1;
   xs.DocType := 'strict';
   xs.PreserveWhitespace := True;
   ...
end;

That simplifies usage of the object to:

var
   xs: TXHTMLStream;
begin
   xs := TXHTMLStream.Create(filename, UTF32);
   xs.Save(xhtmlDocument);

Except now Delphi complains that my new constructor hides the old constructor.

Method 'Create' hides virtual method of base type 'TXMLStream'

i certainly didn't mean to hide the ancestor create - i want both.

How do i add a constructor (with a different signature) to a descendant class, while keeping the ancestor constructor so it can still be used?

解决方案

My immediate reaction is to use the overload keyword, as in:

TCellPhone = class(TComputer)
public
    constructor Create(Cup: Integer; Teapot: string); reintroduce; overload; virtual;
end;

Edit: Thanks Ian for the edit, which makes an answer out of my answer. I would like to think that I got it for bravery, so I am going to contribute a fuller example:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type

TComputer = class(TObject)
public
    constructor Create(Cup: Integer); virtual;
end;

TCellPhone = class(TComputer)
public
    constructor Create(Cup: Integer; Teapot: string); reintroduce; overload; virtual;
end;

{ TComputer }

constructor TComputer.Create(Cup: Integer);
begin
  writeln('constructed computer: cup = ', Cup);
end;

{ TCellPhone }

constructor TCellPhone.Create(Cup: Integer; Teapot: string);
begin
  inherited Create(Cup);
  writeln('constructed cellphone: Teapot = ', Teapot);
end;

var
  C1, C2, C3: TComputer;

begin
  C1 := TComputer.Create(1);
  Writeln;
  C2 := TCellPhone.Create(2);
  Writeln;
  C3 := TCellPhone.Create(3, 'kettle');
  Readln;
end.

with the result being:

constructed computer: cup = 1

constructed computer: cup = 2

constructed computer: cup = 3
constructed cellphone: Teapot = kettle

这篇关于Delphi:如何向后代添加不同的构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆