Java继承而不强制转换

标签 java oop generics binary-tree

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/

相关文章:

java - 压缩要通过 RMI 发送的 Java HashMap

java - Java中如何从对象列表中获取单个对象

java - Firebase Android 方法检查 Firebase 数据库中是否存在用户个人资料信息

C++使用迭代器将函数映射到可迭代对象上

c# - 使用 Int64 进行通用转换

java - 编译代码时出现非法的起始表达式错误

c++ - 来自 C 的 Lua 中的 OOP

Java监听器实现

java - 理解Java new Class[]数组和实现

Java 通用构建器