Как использовать тип расширенного универсального типа в классе?

1

Скажем, у меня есть несколько классов следующим образом:

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?

Теги:
generics

2 ответа

6
Лучший ответ

Также объявляйте 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;
}
  • 0
    Я боялся, что это будет единственный ответ. Нет способа объявить это, не добавляя его каждый раз как отдельный тип?
  • 1
    Единственный способ, которым я мог видеть, что вам нужен только один, - это если вы можете удалить TB . Если бы вы могли создать класс Herd<TA extends A> который вы могли бы использовать для каждого TA , вы могли бы объявить public class C<TA extends A> , использовать Herd<TA> вместо TB внутри C , а затем объявить public class HorseHerder extends C<Horse> чтобы расширить это.
Показать ещё 1 комментарий
1

Вам придется пройти оба типа общих типов. Так, например:

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; }
}
  • 0
    Предпочел бы подход Эрика Робертсона. Использование чего-либо до объявления всегда сбивает с толку. Здесь вы используете TA Type и объявляете его после использования :)
  • 0
    @Vyncent Согласен. Я оставлю этот ответ здесь, чтобы показать, что это может быть сделано наоборот.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню