Вопрос-ответ

Java Generics With a Class & an Interface - Together

Обобщения Java с классом и интерфейсом - вместе

Я хочу иметь объект класса, но я хочу заставить любой класс, который он представляет, расширять класс A и реализовывать интерфейс B.

Я могу сделать:

Class<? extends ClassA>

Или:

Class<? extends InterfaceB>

но я не могу сделать и то, и другое. Есть ли способ сделать это?

Переведено автоматически
Ответ 1

На самом деле, вы можете делать, что хотите. Если вы хотите предоставить несколько интерфейсов или класс плюс интерфейсы, ваш подстановочный знак должен выглядеть примерно так:

<T extends ClassA & InterfaceB>

Смотрите Руководство по обобщениям по ссылке sun.com, в частности, раздел "Параметры ограниченного типа" внизу страницы. На самом деле вы можете перечислить более одного интерфейса, если хотите, используя & InterfaceName для каждого из них, который вам нужен.

Это может быть сколь угодно сложно. Чтобы продемонстрировать, смотрите объявление JavaDoc Collections#max, которое (заключенное в две строки) является:

public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)

почему так сложно? Как сказано в часто задаваемых вопросах по Java Generics: Для сохранения бинарной совместимости.

Похоже, что это не работает для объявления переменных, но это работает при установлении общих границ для класса. Таким образом, чтобы сделать то, что вы хотите, вам, возможно, придется перепрыгнуть через несколько обручей. Но вы можете это сделать. Вы можете сделать что-то вроде этого, установив общую границу для вашего класса, а затем:

class classB { }
interface interfaceC { }

public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}

чтобы получить variable это имеет ограничение, которое вы хотите. Для получения дополнительной информации и примеров ознакомьтесь со страницей 3 книги Обобщения в Java 5.0. Обратите внимание, в <T extends B & C> имя класса должно быть первым, а интерфейсы - следующими. И, конечно, вы можете перечислить только один класс.

Ответ 2

Вы не можете сделать это с помощью параметров "анонимного" типа (т. Е. подстановочных знаков, которые используют ?), но вы можете сделать это с помощью параметров "именованного" типа. Просто объявите параметр типа на уровне метода или класса.

import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
T t;
}
2023-10-15 06:57 java class generics