Delphi:如何为后代添加不同的构造函数?

Ian*_*oyd 8 delphi constructor delphi-5 constructor-chaining

更新:我最初的例子有点复杂.这是一个简单的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 := Encoding;
   xs.XmlVersion := 1.1;
   xs.DocType := 'strict';
   xs.PreserveWhitespace := True;
   ...
end;
Run Code Online (Sandbox Code Playgroud)

这简化了对象的使用:

var
   xs: TXHTMLStream;
begin
   xs := TXHTMLStream.Create(filename, UTF32);
   xs.Save(xhtmlDocument);
Run Code Online (Sandbox Code Playgroud)

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

方法'Create'隐藏基类型'TXMLStream'的虚方法

我当然不是故意隐藏祖先创造 - 我想要两者.

如何将一个构造函数(具有不同的签名)添加到后代类,同时保留祖先构造函数以便仍然可以使用它?

Muh*_*uri 8

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

TCellPhone = class(TComputer)
public
    constructor Create(Cup: Integer; Teapot: string); reintroduce; overload; virtual;
end;
Run Code Online (Sandbox Code Playgroud)

编辑:感谢Ian的编辑,这是我的回答.我想我是勇敢的,所以我将提供一个更全面的例子:

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.
Run Code Online (Sandbox Code Playgroud)

结果是:

constructed computer: cup = 1

constructed computer: cup = 2

constructed computer: cup = 3
constructed cellphone: Teapot = kettle
Run Code Online (Sandbox Code Playgroud)

  • 为了强化之前的评论,"重新引入"完全等同于本地形式的_suppress警告W1010_.就是这样. (5认同)