![](/img/trans.png)
[英]Java: When I Instantiate a Subclass of an Abstract Class It Doesn't Recognize the Constructor of its Superclass
[英]Why doesn't this generic recognize its superclass boundary (Java)?
我有一個對象實例系統,其中包含對定義對象的引用。 我為每個繼承樹都有一個頂級類。 實例對象具有對應定義類的通用引用。
在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
? Bear最終被定義為extends Animal<? extends BearDef>
extends Animal<? extends BearDef>
。
[ 編輯 ]更奇怪的是,如果我改變了熊類線:
abstract class Bear<D extends BearDef> extends Animal<BearDef> { }
(在這種情況下D未被使用且無關緊要)它仍然不起作用。 擦除D和以下行解決了上面代碼中的錯誤(但不能幫助我做我需要做的子類定義):
abstract class Bear extends Animal<BearDef> { }
你使用的是原始類型Bear
,實際上它應該用一種BearDef
參數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
。 也就是說,它顯然並非總是如此簡單,你的實際情況可能不允許這樣。
這也可以:
Bear<?> bear = new BlackBear();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.