在了解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
答案 0 :(得分:1)
This documentation on class constructor methods应该有助于指导您,doubly-linked list example。我猜测btree3
的构造函数会初始化NodeNum
,Prev
,Left
和Right
。因此,您的EqTree
构造函数应该看起来像这样:
function ThisNode = EqTree(NodeNum)
args = {};
if (nargin > 0)
args = {NodeNum};
end
ThisNode = ThisNode@btree3(args{:});
% Other initializations specific to EqTree objects
end
您可能还需要在此处重新初始化Prev
,Left
和Right
,以便它们是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