使用继承的对象列表

时间:2013-12-20 01:35:45

标签: delphi inheritance

我试图创建一个对象结构,其中一个对象包含其他对象的列表。我有这两个类的基类,类似于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>

我在这里忽视/做错了什么?

2 个答案:

答案 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