Введите аргументы в объявлениях подкласса
В настоящее время я изучаю дженерики и с трудом понимаю некоторые их аспекты. Я чувствую, что что-то упустил, поэтому вопрос может показаться глупым.
Я понимаю, что есть:
- Заполнители, известные как "формальные параметры типа".
- Фактические "аргументы типа".
Вот пример кода, который у меня есть с обобщениями и цепочкой методов, которые работают:
class Clothing <T> {
String material;
String color;
T setMaterial (String material) {
this.material = material;
return (T) this;
}
T setColor (String color) {
this.color = color;
return (T) this;
}
}
class Jeans extends Clothing <Jeans> {
}
class Pants extends Clothing <Pants> {
}
class Executor {
public static void main(String[] args){
Jeans jeansPair = new Jeans().setMaterial("cotton").setColor("green");
}
}
Проблема в том, что я не понимаю, почему arugment типа, такой как Jeans и Pants, предоставляется в объявлениях подкласса, а не в экземплярах, подобных тому, что в методе main.
Я был бы признателен, если бы вы предоставили ссылку на это правило - я искал много информации, такой как ограниченные параметры, необработанные типы, стирание и т. Д., Но не совсем нашел то, что искал.
Спасибо
1 ответ
Кроме того: вам, вероятно, будет проще с этими обобщениями, если вы будете использовать шаблон компоновщика, а не изменяемый шаблон, который вы здесь описываете. Я только что ответил на связанный вопрос, который дает пример такой структуры строителя.
Jeans
а также Pants
являются конкретными типами без универсального параметра, поэтому при их создании вы просто говорите new Jeans()
/ new Pants()
; у них нет универсального типа, который может указать вызывающая сторона. Поскольку они также расширяют универсальный тип, вы можете сказать:
Clothing<Jeans> jeans = new Jeans()....;
если вы хотите сослаться на объект по его родителю общего типа. Это ничем не отличается от любых других отношений типа родитель / потомок, таких как List<String>
против ArrayList<String>
, Эти классы просто жестко кодируют значение универсального типа.
Вы можете представить себе копирование методов в Clothing
в Jeans
а также Pants
и замена T
с Jeans
а также Pants
соответственно, если это поможет вам понять, что делают эти классы.
Что касается того, почему аргумент типа предоставляется в объявлениях подкласса, это стилистический выбор, нет правила относительно того, когда его следует использовать. Хорошо, когда у вас есть конечное число типов, которые можно / нужно использовать в качестве универсального типа, так как теперь вызывающим объектам не нужно явно указывать тип каждый раз. Однако в "универсальном" случае, когда универсальный тип представляет произвольное число различных конкретных типов, этот шаблон вреден, поскольку автору класса необходимо определить новый подкласс для каждого данного типа.