Скажем, у меня есть несколько классов следующим образом:
class A { }
class B<TA extends A> { }
class C<TB extends B<? extends A>> {
TA varOfTypeTA; // this throws an error obviously
}
Как я могу определить тип varOfTypeTA
как любой TB TA?
Я знаю, что могу определить его как A varOfTypeTA
, но я хочу, чтобы он был типа TA
not A
Я попытался заставить его определить TA с class C<TB extends B<TA extends A>>
поэтому я могу использовать TA
, но это вызывает синтаксическую ошибку.
Чтобы уточнить, если я затем определяю эти классы:
class Horse extends A { }
class HorseHerd extends B<Horse> { }
class HorseHerder extends C<HorseHerd> {
Horse getFavoriteHorse() { return varOfTypeTA; } // varOfTypeTA defined in class C must be of type Horse, otherwise I have to cast
}
Как я могу сделать varOfTypeTA
типа Horse
?
Также объявляйте TA
как общий в том же классе.
public class C<TA extends A, TB extends B<TA>> {
TA varOfTypeTA;
}
Затем вы можете использовать TA
в своем классе.
class HorseHerder extends C<Horse, HorseHerd> {
Horse getFavoriteHorse() { return this.varOfTypeTA; }
}
Я также был удивлен, узнав, что порядок декларации здесь, похоже, не имеет значения. Хотя я бы предпочел сначала объявить TA
, я обнаружил, что этот код также компилирует:
public class C<TB extends B<TA>, TA extends A> {
TA varOfTypeTA;
}
Вам придется пройти оба типа общих типов. Так, например:
class C<TB extends B<TA>, TA extends A> {
TA varOfTypeTA;
}
class Horse extends A {}
class HorseHerd extends B<Horse> {}
class HorseHerder extends C<HorseHerd, Horse> {
Horse getFavoriteHorse() { return varOfTypeTA; }
}
TB
. Если бы вы могли создать классHerd<TA extends A>
который вы могли бы использовать для каждогоTA
, вы могли бы объявитьpublic class C<TA extends A>
, использоватьHerd<TA>
вместоTB
внутриC
, а затем объявитьpublic class HorseHerder extends C<Horse>
чтобы расширить это.