这个在Delphi中调用的“循环继承”是什么?

时间:2016-08-02 18:19:35

标签: delphi inheritance

前几天我看到了这样的代码:

type
    TcxGridTableControllerAccess = class (TcxGridTableController);

    TMycxGridDBTableView = class (TcxGridDBTableView)
    protected
        function GetViewDataClass: TcxCustomGridViewDataClass; override;
    end;

    TMycxGridViewData = class (TcxGridViewData)
    protected
        function GetFilterRowClass: TcxGridFilterRowClass; override;
    end;

    TMycxGridFilterRow = class (TcxGridFilterRow)
    protected
        procedure SetValue(Index: Integer; const Value: Variant); override;
    end;

    TcxGridDBTableView = class (TMycxGridDBTableView);

TMycxGridDBTableView继承自继承自TMycxGridDBTableView的TcxGridDBTableView。搜索循环继承但仅搜索Java结果。

这叫什么?

Ps:我没有完整的可构建代码。

2 个答案:

答案 0 :(得分:9)

示例代码不符合您的想法。您看到TMycxGridDBTableView被定义为TcxGridDBTableView的后代,然后您会看到TcxGridDBTableView,定义为TcxGridDBTableView的后代。

但是,您在顶部看到的TcxGridDBTableView与您稍后看到的TcxGridDBTableView不同。第一个是指在别处宣布的类,在其他一些单元中。下一个例子是在这个单元中声明一个 new 类,该单元恰好与其他单元的类具有相同的基本名称。

此技术称为插入类。它用于引入新的GetViewDataClass方法,但最终仍然使用相同的类名。使用具有该名称的控件的表单将使用该类的新版本而不是原始版本。这是一种自定义VCL控件的方法,无需编译和安装自定义包。

答案 1 :(得分:6)

您展示的不是循环继承。会发生什么情况dxSample.TMycxGridDBTableView继承自另一个单位的TcxGridDBTableView,可能是cxGridDBTableView.TcxGridDBTableViewdxSample.TcxGridDBtableView继承自dxSample.TMycxGridDBTableView

您的代码相当于:

type
  TcxGridTableControllerAccess = class(TcxGridTableController);

  { Note: this does NOT inherit from the TcxGridDBTableView defined  }
  { a little further on in the source. It inherits from the original }
  { DevEx TcxGridDBTableView.                                        }

  TMycxGridDBTableView = class(cxGridDBTableView.TcxGridDBTableView)
  protected
    function GetViewDataClass: TcxCustomGridViewDataClass; override;
  end;

  TMycxGridViewData = class(TcxGridViewData)
  protected
    function GetFilterRowClass: TcxGridFilterRowClass; override;
   end;

  TMycxGridFilterRow = class(TcxGridFilterRow)
  protected
    procedure SetValue(Index: Integer; const Value: Variant); override;
  end;

  TcxGridDBTableView = class(TMycxGridDBTableView);

所以层次结构是:

cxGridDBTableView.TcxGridDBTableView
                 |
                 v
   dxSample.TMycxGridDBTableView
                 |
                 v
    dxSample.TcxGridDBTableView 

所以dxSample.TMycxGrdiDBTableView 从[{1}}继承,但是从dxSample.TcxGridDBTableView继承,所以没有所谓的循环继承那里。整个误解来自于这样一个事实:不同单元中的两个类具有相同的名称,并且第一个声明并不完全限定它继承的类。

现在,如果有人将单位cxGridDBTableView.TcxGridDBTableView放在dxSample的{​​{1}}子句中,则使用cxridDBTableView,而不是原始的DevEx类。这称为插入

当人们想要修改VCL和FireMonkey的行为时,看到像

这样的插入类并不罕见
uses

dxSample.TCxGridDBTableView

你展示的代码是后者。