【问题标题】:Inheritance - Can base class functions allocate derived class data?继承 - 基类函数可以分配派生类数据吗?
【发布时间】:2017-08-13 15:05:53
【问题描述】:

在这位退休的硬件工程师学习 Matlab 面向对象编程时,请温柔对待他。

我对具有一系列特殊功能的二叉树类有多种需求,用于遍历、修剪、添加、重新连接简单的二叉树。我用大约 20 种方法编写了我自己的类(classdef btree3

接下来,我为继承二叉树(classdef 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.左

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   

【问题讨论】:

  • 我猜你还没有为 EqTree 类实现一个新的构造方法?有的话可以发一下吗?
  • 嗯,我打算这样做,但也许它没有正确完成?我似乎无法在此评论中发布代码,因此我将其添加到原始帖子中。
  • 我确实注意到,虽然 Z1=EqTree 有效,但 Z2=EqTree(100) 并没有像它告诉我的那样,我不能设置 EqTree 的只读属性 'NodeNum,所以 btree3 对象是已分配,但我可能需要一种设置 NodeNum 的方法。

标签: matlab class oop inheritance


【解决方案1】:

This documentation on class constructor methodsdoubly-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 对象(即ThisNode.Prev = EqTree.empty;)。

对于像AddNodeLeft 这样创建给定类的对象的其他方法,您可以遵循linked-list example 中的模式并将您的方法重写为接受给定类的对象而不是在内部创建一个:

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

然后这样称呼它:

ThisNode.AddNodeLeft(EqTree(newNodeNum));

【讨论】:

  • 谢谢。我实际上使用了双链表示例来进行初始构造,但是(如果它在其中)我没有掌握任何我需要了解的特殊方面,我需要了解我的类是否要被继承,所以我将对此进行审查。至于你建议中的想法远远高于我的工资等级,我可能需要几天时间才能更好地理解它,但你对 btree3 初始化的猜测是正确的,所以我怀疑你关于如何解决这个问题的建议可能也是如此。给我几天时间来内化和编辑。谢谢!
  • @LGTrader:是的,那个链表示例只是继承自句柄类,所以它并没有真正深入了解子类/超类构造函数问题。第一个链接应该对此有所帮助。祝你好运!
  • 我将把它标记为已解决,尽管我确实向自己证明了这一点,由于我的补救性编程技能,可能需要太多时间。不过我会继续努力。也就是说,我现在决定做的是,在我的情况下,二叉树是将所有这些东西结合在一起的粘合剂,而不是将 btree3 继承到 EqTree 中,我将简单地将 EqTree 数据放入一个结构中并存储它在给定节点的 btree3 数据中。与我最初的概念验证代码相比,这是一个非常小的变化,并且在我的能力范围内。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 2010-10-05
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多