[英]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.