继承 - 基类函数可以分配派生类数据吗?

时间:2017-03-21 18:49:09

标签: matlab class oop inheritance

在了解Matlab面向对象编程时,请对这位退休的硬件工程师保持温和。

我对二叉树类有多种需求,它具有一系列特殊功能,用于步行,修剪,添加,重新连接简单的二叉树。我用大约20种方法编写了我自己的类(classdef btree3< handle),对它们进行了测试,到目前为止它们都运行良好。

接下来,我编写了一个特定的类,用于继承二叉树的树的一种用法(classdef EqTree< btree3)。通常,这适用于所有btree3方法都可以从EqTree对象调用:

X3 = EqTree;
X3.GenerateRandomTree(50,8);
X3.RenumberTree(100);
disp('Walking X3 tree');
X3.WalkTree;

我遇到的问题是当X3中包含EqTree数据属性时,树中没有任何节点都有它们。所有较低的节点都被分配为btree3对象(我假设),默认情况下,所有btree3方法都知道如何操作,即使它是为EqTree对象调用的。这里显示的是每个对象在完成后的样子:

>> Z1=btree3

Z1 = 

  btree3 with properties:

    NodeNum: []
       Prev: [0×0 btree3]
       Left: [0×0 btree3]
      Right: [0×0 btree3]

>> Z2=EqTree

Z2 = 

  EqTree with properties:

      Operator: []
      LeafData: []
        NodeEq: []
    NodeEqName: []
    OutputType: []
       NodeNum: []
          Prev: [0×0 btree3]
          Left: [0×0 btree3]
         Right: [0×0 btree3]

>> 

我的问题:有没有办法告诉btree3中的继承方法分配树的节点还从派生类中分配数据属性?例如,在上面调用中创建的随机树中,我看到了:

X3 =

具有属性的EqTree:

  Operator: []
  LeafData: []
    NodeEq: []
NodeEqName: []
OutputType: []
   NodeNum: 100
      Prev: [0×0 btree3]
      Left: [1×1 btree3]
     Right: [1×1 btree3]
  
    

X3.Left

  

ans =

带有属性的btree3:

NodeNum: 101
   Prev: [1×1 EqTree]
   Left: [0×0 btree3]
  Right: [0×0 btree3]
  
    

  

有两个问题:

1)未在树中分配EqTree日期,

2)指针不再是同质的,从btree3继承的方法在向上走树并在根处找到EqTree对象时会失败。

如果需要,我可以将树分配为btree3对象,然后使用EqTree数据填充数据(如果EqTree类是独立的)。

我希望问题很清楚,但如果有必要,可以发布更多代码。

谢谢!

Re:EqTree构造函数:EqTree被分配,如果提供,则设置btree3的NodeNum字段:

classdef EqTree < btree3
    properties(SetAccess = private)
        Operator    % Logic, math or function
        LeafData    % Timetable or fixed values
        NodeEq      % Equation node represents
        NodeEqName  % Name that is used in higher equations
        OutputType  % Float, Integer, timetable, boolean, etc.
    end

    methods
        function ThisNode = EqTree(NodeNum)
            if (nargin > 0)
                ThisNode.NodeNum = NodeNum;
            end
        end

Re:用于添加节点的btree3类方法:

为了更加清楚,上面使用的btree3方法GenerateRandomTree调用btree3中的其他方法来实际分配新成员到树中。当添加到树的左侧时,btree3调用AddNodeLeft方法,该方法作为btree3类的一部分,只知道分配新的btree3对象。所有这些在EqTree类继承和调用时都有效,但新对象是btree3对象,而不是EqTree对象。我希望了解如何在这里分配派生类对象:

function AddNodeLeft(ThisNode, newNodeNum)
% Add newNode on left after ThisNode.
    if ThisNode.Left.exists
        error('addNodeLeft: Left side in use')
    end
    newNode = btree3(newNodeNum);
    newNode.Prev = ThisNode;
    ThisNode.Left = newNode;
end   

1 个答案:

答案 0 :(得分:1)

This documentation on class constructor methods应该有助于指导您,doubly-linked list example。我猜测btree3的构造函数会初始化NodeNumPrevLeftRight。因此,您的EqTree构造函数应该看起来像这样:

function ThisNode = EqTree(NodeNum)
    args = {};
    if (nargin > 0)
        args = {NodeNum};
    end
    ThisNode = ThisNode@btree3(args{:});
    % Other initializations specific to EqTree objects
end

您可能还需要在此处重新初始化PrevLeftRight,以便它们是empty EqTree个对象(即{{ 1}})。

对于创建给定类对象的ThisNode.Prev = EqTree.empty;之类的其他方法,您可以按照linked-list example中的模式并将方法重写为 accept 对象一个给定的类而不是在内部创建

AddNodeLeft

然后这样称呼它:

function AddNodeLeft(ThisNode, newNode)
% Add newNode on left after ThisNode.
    if ThisNode.Left.exists
        error('addNodeLeft: Left side in use')
    end
    % Probably also want to check that ThisNode and newNode are the same class!
    newNode.Prev = ThisNode;
    ThisNode.Left = newNode;
end