— Привет! Я продолжу лекцию Элли про Generic’и. Готов слушать?

— Ага.

— Тогда начинаем.

Факт первый. У методов класса тоже могут быть свои типы-параметры.

— Да, я знаю.

— Нет, я имею ввиду именно свои типы-параметры:

Пример
class Calculator
{
  T add(T a, T b); //сложить
  T sub(T a, T b); //отнять
  T mul(T a, T b); //умножить
  T div(T a, T b); //делить
}

Это типы-параметры именно метода(ов). У класса параметров нет. Можно даже объявить методы статическими и вызывать их без использования объекта.

— Ясно. Смысл типов-параметров в методах такой же, как и в классах?

— Ага. Но есть и кое-что новое.

Как ты уже знаешь, в описании типа можно использовать wildcard. Тогда представь себе ситуацию:

Пример 1
public void doSomething(List<? extends MyClass> list) 
{
 for(MyClass object : list)
 { 
  System.out.println(object.getState()); //тут все работает отлично.
 }
}

А вот, что случится, если мы захотим добавить в коллекцию новый элемент:

Пример 2
public void doSomething(List<? extends MyClass> list) 
{
 list.add(new MyClass()); //ошибка!
}

Дело в том, что в общем случае в метод doSomething можно передать List с типом элементов не MyClass, а любой из наследников MyClass. А в такой список заносить объекты MyClass уже нельзя!

— Ага. И что же делать?

— Ничего. Прямо в этой ситуации – ничего не сделаешь. Но это дало разработчикам Java повод для размышлений. И они придумали новое ключевое слово – super.

Выглядит его использование практически так же:

List<? super MyClass> list

Но между extends и super есть существенное различие.

«? extends T» обозначает, что класс должен быть наследником T.

«? super T» обозначает, что класс должен быть предком T.

— Ух ты. А где это используется?

— «? super T» используется, когда метод собирается добавлять в коллекцию объект типа T. Тогда это может быть коллекция типа T или любого типа-предка T.

— Ага. Ссылку на объект типа T можно же присвоить любому родительскому типу для T.

— Честно говоря – этот подход используется не очень часто. Тем более, что у него есть и обратная сторона. Пример:

Примеры
public void doSomething(List<? super MyClass> list)
{
 for(MyClass object : list) //ошибка!
 { 
  System.out.println(object.getState()); 
 }
}
public void doSomething(List<? super MyClass> list)
{
 list.add(new MyClass()); //тут все работает отлично.
}

Теперь не работает первый пример.

Т.к. коллекция list может быть даже List<Object> (Object самый верхний родитель MyClass), то фактически мы пишем такой код, а так писать нельзя:

Пример 1
List<Object> list; 

for(MyClass object : list) //ошибка!
{ 
 System.out.println(object.getState()); 
}

— Ясно. Спасибо за интересную лекцию.

— Пожалуйста.

undefined
4
Задача
Java Core, 5 уровень, 2 лекция
Недоступна
ООП - Расставить интерфейсы
Одежду можно (и нужно, пожалуй) носить, продавать и покупать, желательно — со скидкой. Давайте расскажем это миру, и добавим все возможные интерфейсы из Movable, Sellable, Discountable в класс Clothes. Ну а затем — реализуем их методы.
undefined
4
Задача
Java Core, 5 уровень, 2 лекция
Недоступна
ООП - Наследование животных
Рядом с мышью — и гусь велик, но вот рядом с драконом... В этой задаче у нас будут гуси (класс Goose) и драконы (класс Dragon). А также их предки, классы BigAnimal или SmallAnimal, кто чей предок — догадайтесь сами. Затем переопределите для Goose и Dragon метод String getSize(), так, чтобы они выводили строки о размере животного.
undefined
8
Задача
Java Core, 5 уровень, 2 лекция
Недоступна
ООП - машинки
Классифицируем машинки — создадим классы для доступных и дорогих машин, а затем унаследуем от них классы Ferrari и Lanos (сами решите, кого от кого наследовать, но учтите: у валидатора JavaRush по этому поводу мнение строго определённое). В этих классах реализуем методы printlnDesire, которые расскажут о тайных желаниях водителей.
undefined
16
Задача
Java Core, 5 уровень, 2 лекция
Недоступна
ООП - книги
В этой задаче будем создавать книги земных авторов Марка Твена и Агаты Кристи. Разумеется, с помощью классов MarkTwainBook и AgathaChristieBook, которые наследуется от Book. В этих классах нужно реализовать все абстрактные методы, а в родительском классе реализуйте тело метода getOutputByBookType.
undefined
8
Задача
Java Core, 5 уровень, 2 лекция
Недоступна
ООП - исправь ошибки в наследовании
У каждого человека есть рост и вес. Класс Human реализует соответствующие интерфейсы. Но, похоже, в такой реализации закралась ошибка. Обрати внимание на вывод программы. Исправь ошибки в интерфейсах...