gpt4 book ai didi

java - 为什么这个泛型不能识别它的父类(super class)边界(Java)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:09:19 25 4
gpt4 key购买 nike

我有一个对象实例系统,其中包含对定义对象的引用。每个继承树都有一个顶级类。实例对象具有对相应定义类的泛型引用。

在 getter 中使用泛型,顶级对象的子类无需转换即可获得正确的类型定义。但是,再次被子类化的抽象子类不能:

class Def { }

abstract class Animal<D extends Def> {
D def;
D getDef() { return def; }
}

class CatDef extends Def { }
class Cat extends Animal<CatDef> { }

abstract class BearDef extends Def { }
abstract class Bear<D extends BearDef> extends Animal<D> { }

class BlackBearDef extends BearDef { }
class BlackBear extends Bear<BlackBearDef> { }

class AnimalDefTest {
public static void main (String... args) {
Cat cat = new Cat();
CatDef catDef = cat.getDef(); // CatDef works fine

Bear bear = new BlackBear();
BearDef bearDef = bear.getDef(); // Error: Expected Def not BearDef? Why???
BearDef bearDef2 = ((Animal<BearDef>)bear).getDef(); // Works
}
}

为什么 getDef需要 Bear转换为 ( Animal<BearDef> ) 以获得 BearDef ?熊最终被定义为extends Animal<? extends BearDef> .

[编辑] 更奇怪的是,如果我更改 Bear 类行:

abstract class Bear<D extends BearDef> extends Animal<BearDef> { }

(在这种情况下 D 未被使用且无关紧要)它仍然不起作用。删除 D 和下面的行解决了上面代码中的错误(但没有帮助我做我需要做的子类定义):

abstract class Bear extends Animal<BearDef> { }

最佳答案

您正在使用原始类型 Bear实际上它应该用 BearDef 类型参数化.如果你写了

Bear<BlackBearDef> bear = new BlackBear();

Bear<?> bear = new BlackBear();

它会工作得很好。

另一件事:我不确定你打算如何使用它,但在我看来你可能会很好,只是这样做:

abstract class Bear extends Animal<BearDef> {}

class BlackBear extends Bear {
// make use of covariant return type to make BlackBear return correct def
@Override
BlackBearDef getDef() { ... }
}

我这么想的原因是如果你想要一个Bear谁的getDef()方法返回 BlackBearDef , 那Bear引用需要参数化为 Bear<BlackBearDef> .在那种情况下(无论如何对于你的例子)你有效地知道它是一个 BlackBear来自声明的类型,因此您不妨将其称为 BlackBear .也就是说,这显然并不总是那么简单,您的实际情况可能不允许这样做。

关于java - 为什么这个泛型不能识别它的父类(super class)边界(Java)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4146823/

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