繁体   English   中英

Java从抽象类继承

[英]Java inheriting from 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。 但是,欢迎对我的代码“做太多事情”发表评论,或提出类似建议以清理我的代码。 谢谢

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

Set<WaveNode>Set<EchoNode> 不是 Set<Node>的子类, 因此不能 Set<EchoNode>转换为它。 并且您不能使用超类类型( Node )的参数调用remove(WaveNode ..) )。 如果将keySet作为Set<Node> ,可以,或者使用原始类型: Set nei = rec.keySet();

为了提供更多帮助,我尝试理解问题的实质并提出可行的解决方案。 该代码可以完成很多更复杂的工作(请参见上面的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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM