gpt4 book ai didi

class - 使用类引用的多态和继承?

转载 作者:行者123 更新时间:2023-12-03 15:07:33 25 4
gpt4 key购买 nike

下面的控制台应用程序的输出是

Parent
Parent
Parent

而不是

Parent
Child1
Child2

为什么会发生这种情况?此外,如何获得预期的输出?非常感谢!

PS:读完这篇文章仍然没有任何线索related SO post ...

program Project1;

{$APPTYPE CONSOLE}

type
TParent = class;
TParentClass = class of TParent;

TParent = class
public
ID: string;
constructor Create;
end;

TChild1 = class(TParent)
public
constructor Create;
end;

TChild2 = class(TParent)
public
constructor Create;
end;

constructor TParent.Create;
begin
ID := 'Parent';
end;

constructor TChild1.Create;
begin
ID := 'Child1';
end;

constructor TChild2.Create;
begin
ID := 'Child2';
end;

procedure Test(ImplClass: TParentClass);
var
ImplInstance: TParent;
begin
ImplInstance := ImplClass.Create;
WriteLn(ImplInstance.ID);
ImplInstance.Free;
end;

begin
Test(TParent);
Test(TChild1);
Test(TChild2);
Readln;
end.

最佳答案

您的代码的行为方式是因为您的构造函数不是虚拟的。这意味着编译器在编译时绑定(bind)到它们。因此,这意味着无法考虑运行时类型,并且代码始终调用 TParent.Create

为了让程序使用运行时类型进行绑定(bind),需要使用虚方法和多态性。所以你可以通过使用虚拟构造函数来解决你的问题:

program Project1;

{$APPTYPE CONSOLE}

type
TParent = class;
TParentClass = class of TParent;

TParent = class
public
ID: string;
constructor Create; virtual;
end;

TChild1 = class(TParent)
public
constructor Create; override;
end;

TChild2 = class(TParent)
public
constructor Create; override;
end;

constructor TParent.Create;
begin
ID := 'Parent';
end;

constructor TChild1.Create;
begin
ID := 'Child1';
end;

constructor TChild2.Create;
begin
ID := 'Child2';
end;

procedure Test(ImplClass: TParentClass);
var
ImplInstance: TParent;
begin
ImplInstance := ImplClass.Create;
WriteLn(ImplInstance.ID);
ImplInstance.Free;
end;

begin
Test(TParent);
Test(TChild1);
Test(TChild2);
Readln;
end.

输出

ParentChild1Child2

这里的一个经验法则是,每当您使用元类来实例化对象时,您的类构造函数都应该是虚拟的。这个经验法则也有异常(exception),但我个人从来没有在我的生产代码中打破过这个规则。

关于class - 使用类引用的多态和继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23627783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com