gpt4 book ai didi

delphi - 适当的对象创建 - 寻找通用解决方案

转载 作者:行者123 更新时间:2023-12-03 19:02:58 25 4
gpt4 key购买 nike

有 3 个类(可能更多),它们具有相同的过程(过程填充)。它们几乎相同,仅在对象创建方面有所不同。我想要的只是在基类中编写一个通用过程,它将永远取代这种臭名昭著的重复代码。我不太确定,如果我能准确地表达我在做什么,但看看下面的代码看看。

  TGrandFather = class(TObject)

end;

TFather = class(TGrandFather)

end;

TSon = class(TFather)

end;

TGrandson.... and so on...



TGrandFathers = class (TList)
public
procedure Populate(Amount:Integer);
end;

TFathers = class (TGrandFathers)
public
procedure Populate(Amount:Integer);
end;

TSons = class (TFathers)
public
procedure Populate(Amount:Integer);
end;

TGrandsons....
...

procedure TGrandFathers.Populate(Amount:Integer);
var i:integer;
xGrandFather:TGrandFather;
begin
for i := 0 to Amount do
begin
xGrandFather:=TGrandFather.Create;
Add(xGrandFather);
end;
end;

procedure TFathers.Populate(Amount:Integer);
var i:integer;
xFather:TFather;
begin
for i := 0 to Amount do
begin
xFather:=TFather.Create; //this is the point, which makes trouble
Add(xFather);
end;
end;

procedure TSons.Populate(Amount:Integer);
var i:integer;
xSon:TSon;
begin
for i := 0 to Amount do
begin
xSon:=TSon.Create; //this is the point, which makes trouble
Add(xSon);
end;
end;

procedure Grandsons...

谢谢...

最佳答案

要回答您的问题,如果您想走您要去的路线,您可以通过“class of”使用元类。这段代码演示了您将如何实现这一点。层次结构需要清理,但您应该通过此代码了解正在发生的事情的要点。

元类是一个类,其实例是类。这允许您构建一个更通用的框架,因为您可以使用您的元类来创建您需要的类。

type
TGrandFather = class(TObject)

end;

TStrangeHeirarchyClass = class of TGrandFather;

TFather = class(TGrandFather)

end;

TSon = class(TFather)

end;

TGrandFathers = class(TList)
protected
procedure PopulateInternal(aAmount:Integer; aContainedClass:
TStrangeHeirarchyClass);
public
procedure Populate(Amount:Integer);
end;

TFathers = class (TGrandFathers)
public
procedure Populate(Amount:Integer);
end;

TSons = class (TFathers)
public
procedure Populate(Amount:Integer);
end;

implementation

procedure TGrandFathers.Populate(Amount:Integer);
begin
PopulateInternal(Amount, TGrandFather);
end;

procedure TGrandFathers.PopulateInternal(aAmount:Integer; aContainedClass:
TStrangeHeirarchyClass);
var
i:integer;
xFamilyMember:TGrandFather;
begin
for i := 0 to aAmount do
begin
xFamilyMember := aContainedClass.Create;
Add(xFamilyMember);
end;
end;

procedure TFathers.Populate(Amount:Integer);
begin
PopulateInternal(Amount, TFather);
end;

procedure TSons.Populate(Amount:Integer);
begin
PopulateInternal(Amount, TSon);
end;

它的工作方式是元类 TStrangeHeirarchyClass ,您可以像使用常规数据类型一样使用它,它存储您想要使用的基础类。您可以将类型作为参数传递(就像我在上面的代码示例中所做的那样)或将其作为属性或字段存储在类中,如下所示:
  TGrandFathers = class(TList)
private
FContainedClass: TStrangeHeirarchyClass;
public
procedure Populate(Amount:Integer);
property ContainedClass: TStrangeHeirarchyClass read
FContainedClass write FContainedClass;
end;

一旦你设置了这个属性,你就可以使用它来创建它被设置为的类类型的实例。因此,设置 ContainedClass作为 TFather将导致调用 ContainedClass.Create创建 TFather 的实例.

正如大卫在评论中指出的那样,如果您使用元类并覆盖默认构造函数,您将遇到问题。您在构造函数中的代码将永远不会运行。您要么需要使用虚拟构造函数,要么重写现有的 AfterConstruction方法是由构造函数调用的虚拟方法。如果您使用 AfterConstruction,这样的事情就是一个例子。 :
  TGrandFathers = class(TList)
protected
FContainedClass: TStrangeHeirarchyClass;
public
procedure AfterConstruction; override;
procedure Populate(Amount:Integer);
end;

TFathers = class (TGrandFathers)
public
procedure AfterConstruction; override;
end;

TSons = class (TFathers)
public
procedure AfterConstruction; override;
end;

implementation

procedure TGrandFathers.AfterConstruction;
begin
inherited;
FContainedClass := TGrandFather;
// Other construction code
end;

procedure TGrandFathers.Populate(aAmount:Integer);
var
i:integer;
xFamilyMember:TGrandFather;
begin
for i := 0 to aAmount do
begin
xFamilyMember := FContainedClass.Create;
Add(xFamilyMember);
end;
end;

procedure TFathers.AfterConstruction;
begin
inherited;
FContainedClass := TFather;
// Other construction code
end;

procedure TSons.AfterConstruction;
begin
inherited;
FContainedClass := TSon;
// Other construction code
end;

不过,您的层次结构看起来很奇怪。我认为这样的事情会更合适:
type
TRelationType = (ptSon, ptFather, ptGrandfather);

TPerson = class;

TRelation = class(TObject)
strict private
FRelationship: TRelationType;
FRelation: TPerson;
public
property Relation: TPerson read FRelation write FRelation;
property Relationship: TRelationType read FRelationship write FRelationship;
end;

TRelationList = class(TList)
//...
end;

TPerson = class(TObject)
strict private
FPersonName: string;
FRelations: TRelationList;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
property PersonName: string read FPersonName write FPersonName;
property Relations: TRelationList read FRelations;
end;

implementation

procedure TPerson.AfterConstruction;
begin
inherited;
FRelations := TRelationList.Create;
end;

procedure TPerson.BeforeDestruction;
begin
FRelations.Free;
inherited;
end;

关于delphi - 适当的对象创建 - 寻找通用解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31058675/

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