【发布时间】:2013-12-20 01:35:45
【问题描述】:
我正在尝试创建一个对象结构,其中一个对象包含其他对象的列表。我对这两个都有一个基类,类似于TCollection/TCollectionItem,但是是一个非常自定义的实现。
type
TMyItemBase = class;
TMyListBase = class;
TMyItemBaseClass = class of TMyItemBase;
TMyItemBase = class(TObject)
private
FOwner: TMyListBase;
public
constructor Create(AOwner: TMyListBase);
destructor Destroy; override;
property Owner: TMyListBase read FOwner;
end;
TMyListBase = class(TMyObjectBase)
private
FItems: TList;
FItemClass: TMyItemBaseClass;
function New: TMyItemBase;
function GetItem(Index: Integer): TMyItemBase;
public
constructor Create(AOwner: TMyMainObject; const ItemClass: TMyItemBaseClass);
destructor Destroy; override;
function Count: Integer;
procedure Clear;
property Items[Index: Integer]: TMyItemBase read GetItem; default;
end;
implementation
{ TMyItemBase }
constructor TMyItemBase.Create(AOwner: TMyListBase);
begin
FOwner:= AOwner;
end;
destructor TMyItemBase.Destroy;
begin
inherited;
end;
{ TMyListBase }
constructor TMyListBase.Create(AOwner: TMyMainObject; const ItemClass: TMyItemBaseClass);
begin
inherited Create(AOwner);
FItems:= TList.Create;
FItemClass:= ItemClass;
end;
destructor TMyListBase.Destroy;
begin
Clear;
FItems.Free;
inherited;
end;
procedure TMyListBase.Clear;
begin
while FItems.Count > 0 do begin
TMyItemBase(FItems[0]).Free;
FItems.Delete(0);
end;
end;
function TMyListBase.Count: Integer;
begin
Result:= FItems.Count;
end;
function TMyListBase.GetItem(Index: Integer): TMyItemBase;
begin
Result:= TMyItemBase(FItems[Index]);
end;
function TMyListBase.New: TMyItemBase;
begin
Result:= FItemClass.Create(Self);
FItems.Add(Result);
end;
(伪代码,如有错别字见谅)
问题是,当一个新项目被创建时(通过TMyListBase.New),对象被成功创建,但是继承和它的所有字段都没有(被继承的对象的构造函数甚至没有被调用)......
type
TMyItem = class;
TMyItems = class;
TMyItem = class(TMyItemBase)
private
//various unrelated fields
public
constructor Create;
destructor Destroy; override;
//various unrelated properties
end;
TMyItems = class(TMyListBase)
private
function GetItem(Index: Integer): TMyItem;
function New: TMyItem;
public
constructor Create(AOwner: TMyMainObject);
destructor Destroy; override;
property Items[Index: Integer]: TMyItem read GetItem; default;
end;
implementation
{ TMyItem }
constructor TMyItem.Create;
begin
inherited;
//Initialize some fields
end;
destructor TMyItem.Destroy;
begin
//Destroy some fields
inherited;
end;
{ TMyItems }
constructor TMyItems.Create(AOwner: TMyMainObject);
begin
inherited Create(AOwner, TMyItem);
end;
destructor TMyItems.Destroy;
begin
inherited;
end;
function TMyItems.GetItem(Index: Integer): TMyItem;
begin
Result:= TMyItem(inherited Channels[Index]);
end;
function TMyItems.New: TMyItem;
begin
Result:= TMyItem(inherited New);
end;
New 函数似乎有问题,但我无法弄清楚。即使我将项目创建为其预期的项目类,它也会被进一步视为基类,并且没有任何继承的成员可访问(导致访问冲突),因为从不调用继承的构造函数。
我在这里忽略了什么/做错了什么?
【问题讨论】:
-
你可以在你的构造函数中添加 virtual - 特别是如果你正在使用元类
-
我无法想象你为什么不使用泛型
-
@DavidHeffernan 因为幕后还有很多事情发生,这些事情没有必要或不相关。
TCollection不使用泛型 :-) -
你需要在这里使用泛型。拒绝它是疯狂的。 TCollection 是为 Delphi 1 设计的。当然它不使用泛型。您可以使用泛型摆脱大量代码。您仍然需要虚拟构造函数。您确实需要阅读 Nick 的新书并考虑 Spring 容器。
-
@DavidHeffernan 如果有办法在
TList<>中添加其他专有属性和功能,那么它可能会起作用,但它们与我的问题无关,所以我没有将它们包括在我的问题中.
标签: delphi inheritance