我不确定我是否在问正确的问题。如果我错了,请更正。
我有3个模型继承模型,其中一些子类不应该继承父属性。
我们以下面的类为例:
abstract public class Root{
// Has some attributes that must be inherited by it's sub classes
List<Child> children;
}
abstract public class Child extends Root {
// Has the root's attributes, plus additional attributes pertaining to the child class, including the position.
private int position;
}
abstract public class Leaf extends Child {
// this class inherits all attributes of child class but it does not have any children
// How would I exclude the children attribute here?
}
我正在考虑使用接口但是它不允许我为类保存可变数据,就像抽象类一样。例如,我想保存与Child和Leaf类相关的特定变量,例如子项在其父项列表中的位置。
我也不能这样做:
abstract public class Leaf {
// This child does not have a parent, but then again, it's not considered a child either because it comes before the Root who has children.
}
abstract public class Root extends Leaf {
List<Child> children;
}
abstract public class Child extends Root {
private int position;
}
再次,我将如何对此进行建模?
答案 0 :(得分:0)
你的问题很混乱,因为它在现实和编程方面使用了父/子关系而没有说明你的意思。但是,我想我对你的要求有一个大致的了解。
我相信你要找的是复合图案
(参见:https://en.wikipedia.org/wiki/Composite_pattern)
在以下实现中,Child
和Childless
已成为Composite模式的一部分,并通过添加Root
类从Person
抽象出一个额外的图层。< / p>
所以你会有
abstract public class Root {
//attributes that everything has
}
abstract public class Person extends Root {
protected int position; //All children have parents
//other attributes
}
abstract public class Child extends Person {
protected List<Person> children; //But only Child has more children
//other attributes
}
abstract public class Childless extends Person{
//attributes
}
Person
是“组件”,现在有position
字段,因为每个孩子在父母列表中都有一个职位。
Child
是“复合”,现在有children
字段,因为每个非贫瘠的孩子都可以有更多的孩子。
Childless
是“叶子”,因为它不再有更多的孩子。
另外,请注意,子类无法访问private
字段,因此请改用protected
。
答案 1 :(得分:0)
简单地说明没有Leaf
是Child
的子类,移动字段,可以正常工作
abstract public class Node {
private int position; //Every Node can have a position
}
public class InnerNode extends Node { //Renamed for clarity
List<Node> children; //Children can be InnerNodes or Leafs
}
abstract public class LeafNode extends Node {
//As this is no longer an extension of InnerNode, it won't have the children field.
}
这个模型让IMO更有意义。每个LeafNode和InnerNode都被视为节点,但只有InnerNode有子节点。
如果需要,您甚至可以向Node
添加一个抽象的getter来返回子项,并让LeafNode
返回null或空列表:
abstract public class Node {
private int position; //Every Node can have a position
public abstract List<Node> getChildren();
}
public class InnerNode extends Node { //Renamed for clarity
List<Node> children; //Children can be InnerNodes or Leafs
public List<Node> getChildren(){
return new ArrayList<>(children);
}
}
abstract public class LeafNode extends Node {
//As this is no longer an extension of InnerNode, it won't have the children field.
public List<Node> getChildren() {
return new ArrayList<>(); //Empty
}
}
这大致完成了你打算做的事情 - 只有一些节点(InnerNodes)实际上会有子节点,但你可以尝试访问任意Node实例的子节点而不进行转换。现在可以进行以下操作:
Node n = ...
List<Node> children = n.getChildren();