我试图创建一个对象结构,其中一个对象包含其他对象的列表。我有这两个类的基类,类似于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
函数似乎有问题,但我无法弄明白。即使我将项目创建为其预期的项目类,它也会被视为基类,并且没有任何继承的成员可访问(提供访问冲突),因为永远不会调用继承的构造函数。 / p>
我在这里忽视/做错了什么?
答案 0 :(得分:6)
您的TMyItemBase.Create()
构造函数需要声明为virtual
,然后后代类需要override
它。在使用元类类型构造对象时,这很重要。例如:
type
TMyItemBase = class(TObject)
...
public
constructor Create(AOwner: TMyListBase); virtual;
...
end;
constructor TMyItemBase.Create(AOwner: TMyListBase);
begin
inherited Create;
FOwner := AOwner;
end;
type
TMyItem = class(TMyItemBase)
...
public
constructor Create(AOwner: TMyListBase); override;
...
end;
constructor TMyItem.Create(AOwner: TMyListBase);
begin
inherited Create(AOwner);
...
end;
答案 1 :(得分:2)
尝试使用泛型!
type
TMyItem = class
//Implement your class here
end;
//Use it now!
var
MyItemsList:TObjectList<TMyItem>;
// or implement your generic class customization:
type
TVeryMyItemsList = class(TObjectList<TMyItem>)
end;
// Or implement your generic class
type
TMyGeneric<T> = class(TObjectList<T>)
end;
//where T is any type