public class B extends C <A> {
}
Что это значит? Что C должен расширить A? Какое дополнительное ограничение я ставил вместо того, чтобы просто говорить, что B расширяет C?
public class B extends C <A> {
}
Что это значит? Что C должен расширить A? Какое дополнительное ограничение я ставил вместо того, чтобы просто говорить, что B расширяет C?
В этом случае C
- это класс, который может принимать общий параметр, и вы указываете в качестве параметра определенный тип A
. Затем B
расширяет эту специфическую параметризацию C
.
Например, предположим:
class C<T> {
T example();
}
class B extends C<Integer> {
}
Тогда B.example()
вернет Integer
.
Вы определяете класс B, который наследует от класса C, параметризованного с типом A. A должен быть классом или интерфейсом.
например.
class MyStringList extends ArrayList<String>
означает, что MyString
IS AN ArrayList
, который будет содержать только элементы String
. Этот класс затем может определить, например. a concatenate()
, который возвращает конкатенацию всех Strings
в списке.
Из-за этого наследования вы сможете назначить экземпляр переменной List<String>
:
List<String> strings = new MyStringList();
Но вы не сможете присвоить ему переменные типа List
с другими параметрами:
List<Object> objects = new MyStringList(); // does not compile
C<A>
не означает, что C
расширяется A
, это означает, что он может иметь A
как параметр типа.
Это очень похоже на интерфейсы Comparable<T>
и Comparator<T>
в java.
Рассмотрим следующий пример
public class NameSort implements Comparator<Employee> {
public int compare(Employee one, Employee another){
return (int)(one.getName() - another.getName());
}
}
означает, что Компаратор использует объекты Employee для их сортировки с использованием своего имени.
Вы также можете взять еще один пример
List<String> list = new ArrayList<String>();
Эта строка означает, что List
использует String
объекты в качестве параметров
Класс B
является C
.
C
и B
параметризуются с помощью A
. (Это означает, что у них могут быть методы и методы, которые используют методы A
или методы классов, которые происходят от A.)
Классический вариант использования для этого будет заключаться в том, что у вас есть DAO (объект доступа к данным). Вы создаете общий DAO с некоторыми базовыми методами, например GenericDAO
с общим методом save
. Чтобы сделать это, другие DAO могут расширять GenericDAO
, вы параметризуете этот класс с помощью Entity
, и убедитесь, что все ваши Entity
можно сохранить.
Тогда у вас есть GenericDAO<Entity
и множество реализаций этого, например UserDAO extends GenericDAO<User>
, где Пользователь является сущностью.
Это ничего не значит, если только методы, определенные в Class C
или его потомках, для accept или return Тип A.
Таким образом, вы обеспечиваете безопасность типа, накладывая ограничения на "Они могут принимать или возвращать объекты типа A".
public class B extends C <A> {
}