Вложенные расширения в дженериках
У меня есть три класса:
class ClassR {}
class ClassA<T extends ClassR>{}
class ClassB<E extends ClassA<T extends ClassR>> extends ClassA<T> {
void foo(T param) {
}
void bar(E param) {
}
}
Третий класс не компилируется, если я не изменю его на
class ClassB<E extends ClassA<T>, T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
void bar(E param) {
}
}
Есть ли способ сохранить только параметр E, который мне нужно передать при создании ClassB, а T - вывод? Например, было бы удобно использовать:
new ClassB<ClassA<ClassR>>()
вместо:
new ClassB<ClassA<ClassR>, ClassR>()
Ответы
Ответ 1
Этот еще более простой подход может сработать для вас:
class ClassR {}
class ClassA<T extends ClassR>{}
class ClassB<T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
void bar(ClassA<T> param) {
}
}
И использование затем обходит любую ссылку на ClassA
, чтобы стать:
class SubR extends ClassR {}
ClassB<SubR> obj = new ClassB<SubR>();
Ответ 2
Не уверен, что это ответ, который вы хотите, но, конечно же, простейшая версия читает:
class ClassR {
}
class ClassA<T extends ClassR> {
}
class ClassB<T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
}
public void test() {
ClassB<ClassR> classB = new ClassB<>();
}
Ответ 3
Как тип E
extends ClassA
вы можете спокойно опустить параметр типа ClassA
в своем объявлении.
Правильный параметр типа ClassA
применяется во втором параметре ClassB
.
Смотрите ниже код для иллюстрации:
class ClassB<E extends ClassA, T extends ClassR> extends ClassA<T> {
private ClassA ob;
public ClassB(E e, T t) {
super(t);
ob = e;
}
}
Пример использования:
class ClassR {
public ClassR() {};
}
class ClassS extends ClassR {
private int x;
public ClassS(int x) {
super();
this.x = x;
}
}
public static void test() {
ClassS data1 = new ClassS(1);
ClassB <ClassB, ClassS> first = new ClassB<>(null, data1);
ClassS data2 = new ClassS(2);
ClassB <ClassB, ClassS> second = new ClassB<>(first, data2);
}