从抽象类继承的Java

时间:2016-10-17 17:12:19

标签: java inheritance polymorphism abstract-class

我正在创建一个Node类,用于两个相似但根本不同的算法。在它们之间有一些共同的功能,我的想法是创建一个带有共享方法和字段的抽象节点类。从这个抽象类扩展了两个具体子类的WaveNode和EchoNode。

抽象类中的一些方法处理Node的实例,但是我想将这个公共代码用于子类的实例,也就是说,如果你给方法一个WaveNode或一个EchoNode,那么这个方法不需要一个不同的实现。所以我认为最好在抽象类中实现它,并且两个子类都可以使用实现,所以我不必输出两次。但是,当我在我的子类中并且我正在处理WaveNode或EchoNode时,我遇到了编译错误,因为该方法需要一个抽象的Node实例。有没有办法在超类中实现一个方法,而扩展超类的不同类可以使用它的实现。

以下是一个例子。

Set<Node> getNeighs(){
    Set<Node> nei = (Set<Node>) rec.keySet();       
    nei.remove(this);
    return nei;
}

此代码采用映射“rec”并将键集(节点)放入一组节点。删除当前节点并返回其所有邻居。所以WaveNode和EchoNode都使用完全相同的代码。唯一不同的是Set将是WaveNode或EchoNode。我想用超类中的Node实现它,以节省我两次编写它。有可能吗?

修改

发布更多代码:

public abstract class Node {

   private final int id;
   Map<Node, Boolean> rec = new HashMap<Node, Boolean>();


   public Node(int id) {
       this.id = id;
   }


   int getId() {
        return id;
   }

   void addNeigh(Node neigh) {
       rec.put(neigh, false);
   }

   Set<Node> getNeighs() {
       Set<Node> nei = (Set<Node>) rec.keySet();        
       nei.remove(this);
       return nei;
   }

   void printNeighbours() { 
       Set<Node> nei = getNeighs();
       System.out.println(this +" neighbours are: " + nei);
   }

    Node getSilentNeigh() {
        for(Entry<Node, Boolean> entry : rec.entrySet())
        {
            if(!entry.getValue())
                return entry.getKey();
        }   
        return null;
    }



public final class TreeNode extends Node {


    boolean messageSent = false;


    public TreeNode(int id){
        super(id);
    }

    public void sendTok(TreeNode sender){
        rec.put(sender, true);
    }

请注意,我现在按预期工作,因为没有将Node的返回类型转换为TreeNode,这是我自己的错。但是,欢迎任何关于我的代码“做太多”的评论或关于清理我的代码的类似建议。感谢

3 个答案:

答案 0 :(得分:1)

使用泛型执行此操作,而不是专门在Node上键入。将返回签名从Set<Node>更改为Set<? extends Node>,或让子类处理泛型类型而不是其类型。

答案 1 :(得分:0)

Set<WaveNode>Set<EchoNode> 不是 Set<Node>的子类,无法将其转换为它;并且您不能使用超类类型(remove(WaveNode ..))的参数调用Node。如果您keySetSet<Node>,那就没问题,或使用原始类型:Set nei = rec.keySet();

答案 2 :(得分:0)

试图更有帮助,我试图直觉问题的精神,并提出一个可行的解决方案。代码COULD已经完成了许多更复杂的要点(参见上面的Nosretep),但过多的细节可能会影响初学者学习要点;因此,此代码仅提示简单的工作方法。

import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

/* this class does everything that EVERY Node does since it defines what that means; for
 * ANY behaviors that are common to subclasses, here is where they should be implemented.
 */
abstract class Node {
    private final int id;
    private boolean tokenSent = false;

    public Node(int id) {
        this.id = id;
    }

    int getId() {
        return id;
    }

    // common behavior: other things that a Node might wish to do in context of the problem
    public void sendTok() {
        if (!tokenSent) {
            // send token here
            tokenSent = true;
        }
    }

    /* common behavior: this is not really the ideal way to do this, but hopefully it makes
     * sense in the context of the problem being solved; better would be an iterator that
     * visits each node in the list and performs the printing, etc., but this is in the 
     * spirit of the problem
     */
    public void printNeighboursOf(List<Node> list) {
        if (list.size() > 1) {
            System.out.print(this + "[" + getId() + "] has neighbors: ");
            Node node;
            Iterator<Node> iterator = list.iterator();
            while (iterator.hasNext()) {
                node = iterator.next();
                if (!node.equals(this))
                    System.out.print(node + "[" + node.getId() + "] ");
            }
        } else {
            System.out.print(this + " has no neighbors");
        }
        System.out.println();
    }

    /* this method has no implementation in this class (hence its being abstract); each
     * subclass MUST implement it (or their subclasses!), allowing differing algorithms.
     * the signature (method name and parameter list) must be identical for every subclass
     */
    public abstract int doSomeNodeBehavior();
}

/* this class knows and does everything a Node knows and does, and adds a bit more; it
 * can do additional things differently or other than what EchoNode does
 */
class WaveNode extends Node {
    public WaveNode(int id) {
        super(id);
    }

    public void doWaveBehavior() {
        // do something wavy here
    }

    public int doSomeNodeBehavior() {
        // do the wave algorithm
        return 0;
    }
}

/* this class knows and does everything a Node knows and does, and adds a bit more
 * can do additional things differently or other than what WaveNode does
 */
class EchoNode extends Node {
    public EchoNode(int id) {
        super(id);
    }

    public void doEchoBehavior() {
        // do something echoy here
    }

    public int doSomeNodeBehavior() {
        // do the echo algorithm
        return 0;
    }
}

/* it is best to reduce the amount of behavior the Node container (ArrayList in this case)
 * does beyond what is typical for an Abstract Data Type (ADT) element; make the additional
 * behavior in other classes.  visit each node to perform specific behaviors and let the
 * polymorphic behavior determine exactly what to do.  Note: subclass specific behavior is
 * not possible without downcasting, and that MAY be a sign of poor design
 */
public class Nodes {
    public static void main(String[] args) {
        List<Node> list = new ArrayList<Node>();
        list.add(new WaveNode(1));
        list.add(new WaveNode(2));
        Node node = new EchoNode(1);
        list.add(node);
        list.add(new EchoNode(2));

        node.printNeighboursOf(list);
    }
}
相关问题