使用继承的对象列表

 速度coinmer 发布于 2023-02-09 08:46

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

(伪代码,对不起,如果有任何错别字)

问题是,当创建一个新项目(via 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,但我无法弄明白.即使我将项目创建为其预期的项目类,它也会被视为基类,并且没有任何继承的成员可访问(提供访问冲突),因为永远不会调用继承的构造函数.

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

1 个回答
  • 您的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;
    

    2023-02-09 08:55 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有