JavaRush /Курсы /Модуль 2. Java Core /Generics: типизированные классы

Generics: типизированные классы

Модуль 2. Java Core
5 уровень , 2 лекция
Открыта

— Привет! Я продолжу лекцию Элли про 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()); 
}

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

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

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

public class Solution<T extends ClassForGenerics & InterfaceForGenerics>
где ClassForGenerics - родительский класс, а InterfaceForGenerics - имплементируемый интерфейс. Также рекомендую перед решением задач найти информацию (можно посмотреть видео в последней лекции этого раздела) про конструкцию с указанием параметризованного типа до типа возвращаемого, т.е. про конструкции вида

public static <T> ArrayList<T> newArrayList(T... elements)
16 сентября 2025
Я уже смирился с этим😒 Обилие грамматических ошибок сильно удручает, прям по глазам бьёт. Ведь не один год без правок, судя по комментариям. Это конечно не главное, но всё же...
Пётр Уровень 92
3 июня 2025
Ужасная подача материала :(
Ardan Уровень 57
24 января 2025
— Ясно. Спасибо за интересную лекцию. на столько интересно что я ничего не понял
Руслан Никитин Уровень 109
18 августа 2024
Руслан Никитин Уровень 109
18 августа 2024
что такое <? super MyClass> и <? extends MyClass> в примере. Вроде ничего не забыл

public class Main {
    public static void main(String[] args) {
        List<Dog> dogs = new ArrayList<>();
        dogs.add(new Dog());

        List<Cat> cats = new ArrayList<>();
        cats.add(new Cat());

        List<Animal> animals = new ArrayList<>();
        animals.add(new Dog());
        animals.add(new Cat());

        // Применяем методы PECS
        processAnimals(animals);
        processAnimals(dogs);
        processAnimals(cats);

        addDogs(animals);
        addDogs(dogs);
    }

    // Producer Extends Извлечение данных из коллекции
    public static void processAnimals(List<? extends Animal> animals) {
        for (Animal animal : animals) {
            System.out.println(animal);
        }
        //animals.add(new Animal()); //ошибка, т.к. animals может быть Dog, Cat
    }

    // Consumer Super Добавление данных в коллекцию
    public static void addDogs(List<? super Dog> dogs) {
        dogs.add(new Dog());   // Можно добавить объект типа Dog
        //dogs.add(new Animal()); // ошибка, т.к. граница типа коллекции Dog, но можно положить подкласс
        dogs.add(new Puppy()); // Можно добавить объект типа Puppy, т.к. это подкласс Dog
        System.out.println("Dog added to the list");

        //for (Animal animal : dogs) { //ошибка, т.к. dogs может быть Object
        //    System.out.println(animal); }
    }
}

class Animal {
    @Override
    public String toString() {
        return "I am an Animal";
    }
}

class Dog extends Animal {
    @Override
    public String toString() {
        return "I am a Dog";
    }
}

class Cat extends Animal {
    @Override
    public String toString() {
        return "I am a Cat";
    }
}

class Puppy extends Dog {
    @Override
    public String toString() {
        return "I am a Puppy";
    }
}
<
Goro Уровень 51
3 декабря 2023
Ничего не понял, идем дальше :)
Владимир Кругман Уровень 51 Expert
1 сентября 2023
Что за конструкция с параметром до коллекции

public static <T> ArrayList<T>
В лекции такого не было. Такое ощущение, что лекцию и задания разрабатывали люди в открыве друг от друга
Руслан Никитин Уровень 109
13 августа 2024
это обозначение для типизированного метода

public class Main {
    public static void main(String[] args) {
        String middle = Main.<String>getMiddle("John", "Q.","Public");
        System.out.println(middle);
    }

    @SafeVarargs
    public static <T> T getMiddle(T... args) {
        if (args == null || args.length == 0) {
            throw new IllegalArgumentException("Array must not be null or empty");
        }
        return args[args.length / 2];
    }
}
Main.<String>getMiddle("John", "Q.","Public"); <String> опускают, написал только ради примера, что так тоже можно. А вообще тип будет выведен на основе переданного аргумента. хотя вряд ли тебе актуально)
Валерий Уровень 106 Expert
27 февраля 2023
Чето както совсем тяжко.
jvatechs Уровень 111 Expert
13 февраля 2023
В лекции ни слова про имплементацию интерфейсов, благо ютубу и гуглу смог решить "Несколько суперклассов для дженерика". Советую видео: https://youtu.be/5et8IyafnWE вкратце: имплементация интерфейса после наследования от класса выполняется знаком &.

public class Wolf<T extends Animal & Screamable> {
где Animal - класс родитель Screamable - интерфейс
Сергей Карпеев Уровень 93 Expert
11 сентября 2024
спасибо, очень помогло со второй задачей. даже не представляю, как бы я это решал)
Николай Уровень 111 Expert
21 января 2023
https://javarush.com/groups/posts/2004-teorija-dzhenerikov-v-java-ili-gde-na-praktike-stavitjh-skobki Прочитайте тут, я более менее все понял, может поможет