简体   繁体   English

Java从抽象类继承

[英]Java inheriting from abstract class

I'm creating a Node class for use in two similar but fundamentally different algorithms. 我正在创建一个Node类,以用于两种相似但根本不同的算法。 Having some common functionality between them my idea was to create an abstract node class with shared methods and fields. 他们之间有一些共同的功能,我的想法是创建一个具有共享方法和字段的抽象节点类。 Extend from this abstract class two concrete subclass's WaveNode and EchoNode. 从这个抽象类扩展两个具体的子类WaveNode和EchoNode。

Some of the methods in the abstract class deal with instances of a Node, but I wanted to use this common code with instance of subclass's, that is if you give the method a WaveNode or an EchoNode then the method doesn't need a different implementation. 抽象类中的某些方法处理Node的实例,但我想将此通用代码与子类的实例一起使用,也就是说,如果为该方法提供WaveNode或EchoNode,则该方法不需要其他实现。 。 So I thought it best to implement it in the abstract class and both subclasses can use the implementation so I don't have to type it out twice. 因此,我认为最好在抽象类中实现它,并且两个子类都可以使用实现,因此我不必两次键入它。 However when I'm in my subclass's and I'm dealing with a WaveNode or EchoNode, I'm getting compile errors because the method expects an abstract Node instance. 但是,当我在子类中并且正在处理WaveNode或EchoNode时,会遇到编译错误,因为该方法需要一个抽象Node实例。 Is there a way to implement a method in a super class and different classes extending the super class can use its implementation. 有没有一种方法可以在超类中实现方法,并且扩展超类的不同类可以使用其实现。

An example is below. 下面是一个示例。

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

This code takes a map "rec" and puts the keyset (of Node) into a Set of Node. 此代码采用映射“ rec”,并将(节点的)键集放入节点集。 Removes the current node and returns all of its neighbours. 删除当前节点并返回其所有邻居。 So both WaveNode and EchoNode use exactly the same code. 因此,WaveNode和EchoNode都使用完全相同的代码。 The only different is the Set would be of WaveNode or EchoNode. 唯一不同的是Set将是WaveNode或EchoNode。 I wanted to implement it with Node in the superclass to save me writing it out twice. 我想用超类中的Node来实现它,以免我写两次。 Is it possible? 可能吗?

edit 编辑

Posting some more of the code: 发布更多代码:

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);
    }

Please be aware that I have it working as intended now, it was my own fault for not casting the return type of Node to TreeNode. 请注意,我现在已经按预期工作了,这是我自己的错,因为没有将Node的返回类型转换为TreeNode。 However any comments on my code "doing too much" or similar advice on cleaning up my code is welcome. 但是,欢迎对我的代码“做太多事情”发表评论,或提出类似建议以清理我的代码。 Thanks 谢谢

Use generics to do this instead of typing specifically on Node. 使用泛型来执行此操作,而不是在Node上专门键入。 Change the return signature from Set<Node> to Set<? extends Node> 将返回签名从Set<Node>更改为Set<? extends Node> Set<? extends Node> or have the subclass handle the generic type rather than its type. Set<? extends Node>或让子类处理通用类型而不是其类型。

Set<WaveNode> or Set<EchoNode> is not a subclass of Set<Node> and can't be casted to it; Set<WaveNode>Set<EchoNode> 不是 Set<Node>的子类, 因此不能 Set<EchoNode>转换为它。 and you can't invoke remove(WaveNode ..) with argument of superclass type ( Node ). 并且您不能使用超类类型( Node )的参数调用remove(WaveNode ..) )。 If you would have keySet as Set<Node> it would be ok, or use raw type: Set nei = rec.keySet(); 如果将keySet作为Set<Node> ,可以,或者使用原始类型: Set nei = rec.keySet();

trying to be more helpful, i tried to intuit the spirit of the problem and come up with a workable solution. 为了提供更多帮助,我尝试理解问题的实质并提出可行的解决方案。 there are many more sophisticated points the code COULD have done (cf., Nosretep above), but too much detail can detract from a beginner learning the main point; 该代码可以完成很多更复杂的工作(请参见上面的Nosretep),但是过多的细节可能会影响初学者的学习重点; therefore, this code is only suggestive of a simple working approach. 因此,此代码仅表示一种简单的工作方法。

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