gpt4 book ai didi

Java继承而不强制转换

转载 作者:行者123 更新时间:2023-11-30 07:56:09 24 4
gpt4 key购买 nike

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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com