有没有办法从父类调用子类的Create?下面是这个Duplicate方法,我希望调用子类的构造函数,以便底部的测试成功。
type
IBla<T> = interface(IInvokable)
['{34E812BF-D021-422A-A051-A492F25534C4}']
function GetIntFromIface(): Integer;
function Duplicate(): IBla<T>;
end;
TClassA<T> = class(TInterfacedObject, IBla<T>)
protected
function GetInt(): Integer; virtual;
public
function GetIntFromIface(): Integer;
function Duplicate(): IBla<T>;
end;
TClassB = class(TClassA<Integer>, IBla<Integer>)
protected
function GetInt(): Integer; override;
end;
function TClassA<T>.Duplicate: IBla<T>;
begin
Exit(TClassA<T>.Create());
end;
function TClassA<T>.GetInt: Integer;
begin
Exit(1);
end;
function TClassA<T>.GetIntFromIface: Integer;
begin
Exit(GetInt());
end;
function TClassB.GetInt: Integer;
begin
Exit(2);
end;
procedure TestRandomStuff.Test123;
var
o1, o2: IBla<Integer>;
begin
o1 := TClassB.Create();
o2 := o1.Duplicate();
Assert.AreEqual(o2.GetIntFromIface, 2);
end;
答案 0 :(得分:0)
这似乎有效:
function TClassA<T>.Duplicate: IBla<T>;
begin
//Exit(TClassA<T>.Create());
Exit( ClassType.Create as TClassA<T> );
end;
微妙的是ClassType.Create将创建(在这种情况下)TClassB,并且原始创建TClassA&lt;整数&gt;编译器认为与TClassB不同,因此调用TClassA&lt; T&gt; .GetInt而不是TClassB.GetInt。
但请注意,这会调用TObject中定义的构造函数,并且不会调用子类中定义的任何构造函数。 (感谢David H)
然而,这里也是克服这种限制的解决方案:
interface
type
IBla<T> = interface(IInvokable)
['{34E812BF-D021-422A-A051-A492F25534C4}']
function GetIntFromIface(): Integer;
function Duplicate(): IBla<T>;
end;
TClassA<T> = class(TInterfacedObject, IBla<T>)
protected
function GetInt(): Integer; virtual;
public
constructor Create; virtual;
function GetIntFromIface(): Integer;
function Duplicate(): IBla<T>;
end;
//TClassB = class(TClassA<Integer>)
TClassB = class(TClassA<Integer>, IBla<Integer>)
protected
function GetInt(): Integer; override;
public
constructor Create; override;
function Duplicate(): IBla<Integer>;
end;
procedure Test123;
implementation
constructor TClassA<T>.Create;
begin
inherited Create;
end;
function TClassA<T>.Duplicate: IBla<T>;
begin
Exit(TClassA<T>.Create());
end;
function TClassA<T>.GetInt: Integer;
begin
Exit(1);
end;
function TClassA<T>.GetIntFromIface: Integer;
begin
Exit(GetInt());
end;
constructor TClassB.Create;
begin
inherited Create;
end;
function TClassB.Duplicate: IBla<Integer>;
begin
Result := TClassB.Create;
end;
function TClassB.GetInt: Integer;
begin
Exit(2);
end;
procedure Test123;
var
o1, o2: IBla<Integer>;
begin
o1 := TClassB.Create();
o2 := o1.Duplicate();
Assert( o2.GetIntFromIface = 2);
end;