public class BinaryVertex {
public BinaryVertex parent,left,right;
}
public class BSTVertex extends BinaryVertex {
public void foo() {
left = new BSTVertex();
if(Math.floor(Math.random()*2) == 0) left.foo();
}
}
我正在为学校制作一个树/图 api,从 oop 的角度来处理它。但我试图找出一种方法,让继承类将其一些基类变量视为自己的类型(即,当从 BSTVertex
调用时,parent,left,right 应被视为 BSTVertex
,但被视为 BinaryVertex
。当从 BinaryVertex
调用时),无需强制转换。
我正在考虑泛型,但我不确定在这种情况下如何实现。
更新
很好,不知道你可以在泛型中使用扩展。但我得到了 BSTVertex<T> cannot be converted to T
错误如下:
public class Test {
public static void main(String[] args) {
new AVLVertex();
BSTVertex<BSTVertex> v = new BSTVertex<BSTVertex>();
v.foo();
}
class BinaryVertex<T extends BinaryVertex> {
public T parent, left, right;
}
class BSTVertex<T extends BSTVertex> extends BinaryVertex<T> {
public T foo() {
return this; //error here
}
}
class AVLVertex extends BSTVertex<AVLVertex> {
// this might probably end up being abstract too
}
foo 需要返回与调用者相同类型的顶点,即如果 AVLVertex 调用 foo,它期望获得 AVLVertex 而不是 BSTVertex
最佳答案
是的,您可以像这样使用泛型:
public class BinaryVertex<T extends BinaryVertex<T>> {
public T parent, left, right;
}
public class BSTVertex extends BinaryVertex<BSTVertex> {
public void foo() {
left = new BSTVertex();
if(Math.floor(Math.random()*2) == 0) left.foo();
}
}
同样的方式 Comparable
已实现接口(interface),因此子类接收与 compareTo
相同的类型方法。例如,Integer implements Comparable<Integer>
,所以它是 compareTo
方法接收 Integer
论证。
另请注意,最好像这样创建自己的随机数生成器:
public class BSTVertex extends BinaryVertex<BSTVertex> {
private static final Random r = new Random();
public void foo() {
left = new BSTVertex();
if(r.nextBoolean()) left.foo();
}
}
更新
在您更新的代码中(将来请提出新问题)您无法安全地进行转换,因为您以后可能会编写:
class RBVertex extends BSTVertex<RBVertex>{}
class AVLVertex extends BSTVertex<RBVertex>{}
从编译器的角度来看这是可以的,但是你的 AVLVertex
通用参数实际上不是 AVLVertex
。这就是为什么 foo()
中出现编译错误的原因。方法:你的类稍后可能会以这样的方式扩展,这将使你的T
与此不兼容。
您可以通过进行未经检查的强制转换来解决此问题:
@SuppressWarnings("unchecked")
public T foo() {
return (T) this;
}
这样如果误创建class AVLVertex extends BSTVertex<RBVertex>{}
,它仍然会编译,但是在调用 AVLVertex.foo()
时你可能有一个运行时 ClassCastException
.
关于Java继承而不强制转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32643869/