User Павел
Павел
11 уровень

Зачем нужно наследование интерфейсов?

Статья из группы Java Developer
Зачем нужны интерфейсы? Зачем нужно наследование интерфейсов? Зачем нужен полиморфизм? Для тех, кто почитал и понял, как делать наследование интерфейсов, но не понял, зачем. В прошлый раз, на примере обычной семьи Ивановых мы разобрали, зачем нужны интерфейсы. Продолжаем оцифровывать беспокойное семейство. У каждого человека есть какие-то привычки, которые он ни от кого не наследовал или никому не передавал по наследству - его личные привычки. У нас задача: наделить каждого члена семьи уникальными привычками. Переводим в плоскость Java: надо реализовать в классах уникальные методы, которые будут принадлежать только этим классам. Что же, вперед! Это Петя:

class Петя implements ПривычкиПапы, ПривычкиМамы {

//это личные Петины привычки
public void ковырятьВНосу () {
System.out.println("Ковырь-ковырь");
    }

//это унаследованные привычки
@Override
public void прихлюпывать() {
     System.out.println("Хлюп");
   }

@Override
public void поджимать () {
System.out.println("Поджать губки");
    }
}
Это Папа:

class Папа implements ПривычкиПапы {

//это личные Папины привычки
public void чесатьБороду () {
System.out.println("Чешу бороду");
    }

//это переданные привычки
   @Override
    public void прихлюпывать() {
     System.out.println("Хлюп");
   }
}
Это Мама:

class Мама implements ПривычкиМамы{

//это личные Мамины привычки
public void хлопатьРесницами () {
System.out.println("Хлоп-хлоп");
    }

//это переданные привычки
@Override
public void поджимать() {
System.out.println("Поджать губки");
    }
}
Идеально! Все работает как надо! В первой статье, говорилось, что программа — это отражение реального мира. Самое интересное свойство реальности – это все время меняться. Семья Ивановых не стала исключением, у них появилась лапочка-дочка по имени Маша. И она унаследовала от Мамы привычку хлопать ресницами, а от Папы прихлюпывать. Надо вносить изменения в нашу программу. Зачем нужно наследование интерфейсов? - 1Да ладно, это не так и сложно, главное мыслить логически. Ведь все знают зачем нужны интерфейсы. Сейчас создадим interface ПривычкиМаши, опишем там метод хлопатьРесницами() и прихлюпывать() имплементируем его к Маше и дело в шляпе. Ну и что, что методы с таким названием уже реализованы в других интерфейсах, один раз можно. Зачем нужно наследование интерфейсов? - 2Действительно, кто знает какие планы у семейства Ивановых, если родиться Сережа, который унаследует привычки от Папы, Мамы, ПраДедушки и еще кого-то из четвертого колена, каждый раз создавать интерфейс, типа: interface ПривычкиСережи, и там объявлять методы, которые уже могут быть объявлены сотни раз в других интерфейсах? Через пару, тройку поколений мы рискуем получить интерфейсы с кучей одинаковых методов, которые уже описаны в других интерфейсах, и если надо будет изменить наименование какой-нибудь привычки (а это вполне реально – ведь мир меняется), то как разобраться в этом спагетти, я не представляю. Остается только сидеть и мечтать о чуде. Зачем нужно наследование интерфейсов? - 3Вот если бы для каждой привычки был свой интерфейс. Двайте представим:

public interface ПривычкаПрихлюпывать {
    public void прихлюпывать();
}
public interface ПривычкаПоджимать {
    public void поджимать();
}
public interface ПривычкаКовырятьВНосу {
    public void ковырятьВНосу();
}
public interface ПривычкаХлопатьРесницами {
    public void хлопатьРесницами();
}
public interface ПривычкаЧесатьБороду {
    public void чесатьБороду();
}
А потом, можно было бы как в лего, с помощью множественного наследования из отдельных привычек набрать нужный нам интерфейс привычек отдельного члена семейства. Как-то так:

public interface ПривычкиМамы extends ПривычкаПоджимать, ПривычкаХлопатьРесницами {
    }
public interface ПривычкиПапы extends ПривычкаЧесатьБороду, ПривычкаХлюпать {
    }
public interface ПривычкиПети extends ПривычкаПоджимать, ПривычкаХлюпать,ПривычкаКовырятьВНосу {
    }
public interface ПривычкиМаши extends ПривычкаХлюпать, ПривычкаХлопатьРесницами {
    }
А потом просто имплементировать нужный интерфейс нужному классу, например, Маме:

class Мама implements ПривычкиМамы{
@Override
public void хлопатьРесницами () {
System.out.println("Хлоп-хлоп");
    }

@Override
public void поджимать() {
System.out.println("Поджать губки");
    }
}
Так же можно было бы поступить с Папой, Петей и Машей. И потом, при расширении семейства Ивановых, проблем бы с привычками не было, мы просто бы их тасовали через наследование на уровне интерфейсов, как ингредиенты в салате, и не плодили кучу методов с одинаковым наименованием. Эх, мечты, мечты… Зачем нужно наследование интерфейсов? - 4Нарисованный человек прав, так на самом деле можно - теперь симуляция семейства Ивановых спасена! Внимательный читатель, может задать вопрос: "А зачем плодить интерфейсы для каждого члена семьи? У нас есть набор действий - сразу имплементировать нужному классу." Представим что во многих параллельных мирах существуют двойники Пети, и всем Петям надо имплементировать interface ПривычкиПети

interface ПривычкиПети extends ПривычкаПоджимать, ПривычкаХлюпать,ПривычкаКовырятьВНосу 

class ПетяВселеннаяХ implements ПривычкиПети
class ПетяВселеннаяY implements ПривычкиПети
// и т.д.
А если бы общего интерфейса не было

class ПетяВселеннаяХ implements ПривычкаПоджимать, ПривычкаХлюпать,ПривычкаКовырятьВНосу
class ПетяВселеннаяY implements ПривычкаПоджимать, ПривычкаХлюпать,ПривычкаКовырятьВНосу
// и т.д.
Получается более объемный повторяющийся код. Наследование интерфейсов делает приложение более гибким к изменениям, в частности — можно решить проблемы с повторяющимися методами. Еще раз обратите внимание, что множественное наследование интерфейсов — разрешено.
Комментарии (6)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Василий Бабин Уровень 28, Москва, Россия Expert
27 ноября 2021
Спасибо, хорошая статья! Но, есть ошибка которая несведущих введёт в заблуждение, тут в коде думаю надо: "Представим что во многих параллельных мирах существуют двойники Пети, и всем Петям надо имплементировать interface ПривычкиПети

interface ПривычкиПети extends ПривычкаПоджимать, ПривычкаХлюпать, ПривычкаКовырятьВНосу

class ПетяВселеннаяХ implements ПривычкиПети
class ПетяВселеннаяY implements ПривычкиПети
// и т.д.
"
Котики Уровень 20, Москва, Russian Federation
25 ноября 2021
А зачем плодить интерфейсы для каждого члена семьи? У нас есть набор действий - сразу имплементировать нужному классу. Ну только если сохранить условие, что Петя наследует все привычки - тогда в его класс имплементируются интерфейсы привычки мамы и папы.
Anonymous #2583212 Уровень 33
22 ноября 2021
Хороший забавный пример)