簡體   English   中英

在Java中建模選擇性繼承特征?

[英]Modelling selective inheritance trait in Java?

我不確定是否要問正確的問題。 如果我錯了,請更正它。

我有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;
}

同樣,我將如何建模呢?

您的問題令人困惑,因為它在現實和編程方面使用了父子關系,而沒有指定您的意思。 但是,我想我對您的要求有一個大致的了解。

我相信您正在尋找的是復合模式
(請參閱: https : //en.wikipedia.org/wiki/Composite_pattern

在以下實現中, ChildChildless已成為Composite模式的一部分,並通過添加Person類從Root提取了額外的一層。

所以你會

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

不讓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都被視為節點,但是只有InnerNodes擁有子級。

如果需要,您甚至可以向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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM