Ho un sistema di istanze di oggetto che contengono un riferimento a un oggetto definizione. Ho una classe di primo livello per ogni albero di ereditarietà. L'oggetto istanza ha un riferimento generico alla classe di definizione corrispondente.Perché questo generico non riconosce il limite della superclasse (Java)?
Utilizzando i generici nel getter, una sottoclasse dell'oggetto di livello superiore può ottenere il giusto tipo di definizione senza eseguire il cast. Tuttavia, una sottoclasse astratta che è ancora una volta una sottoclasse non può:
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
}
}
Perché getDef
richiedono un Bear
essere gettato a (Animal<BearDef>
) per ottenere un BearDef
? L'orso è definitivamente definito come extends Animal<? extends BearDef>
.
[Modifica] Ancora più strano, se cambio la linea di classe dell'orso:
abstract class Bear<D extends BearDef> extends Animal<BearDef> { }
(In questo caso D è inutilizzato ed è irrilevante) è ancora non funziona. Cancellare D e la seguente riga risolve l'errore nel codice di cui sopra (ma non mi aiuta fare quello che devo fare con le definizioni sottoclasse):
abstract class Bear extends Animal<BearDef> { }
+1: Beat me ad esso. – Powerlord
+1 anche da me. –
Quella * specie di * ha senso, ma dal momento che sa che è * almeno * un BearDef, non dovrebbe essenzialmente assumere ciò che si ha nella seconda linea? – Nicole