JavaRush/Курси/Java Syntax Zero/Сутність інтерфейсів

Сутність інтерфейсів

Відкрита

1. Здібності

Аби краще зрозуміти переваги інтерфейсів і способи їх використання, слід поговорити про більш абстрактні речі.

Клас — це зазвичай модель певного об'єкта. А інтерфейс здебільшого описує не об'єкти, а їхні здібності або ролі.

Сутність інтерфейсів

Наприклад, такі речі, як машина, велосипед, мотоцикл і колесо найкраще подати у вигляді класів і об'єктів. А такі їхні здібності, як «можу їздити», «можу перевозити людей», «можу стояти», краще подати у вигляді інтерфейсів. Наведемо кілька прикладів:

Код Опис
interface Movable
{
   void move(String newAddress);
}
відповідає здібності рухатися
interface Driveable
{
   void drive(Driver driver);
}
відповідає здібності бути керованим
interface Transport
{
   void addStuff(Object stuff);
   Object removeStuff();
}
відповідає здібності перевозити вантажі
class Wheel implements Movable
{
   ...
}
клас Wheel (колесо) має здібність рухатися
class Car implements Movable, Driveable, Transport
{
   ...
}
клас Car (автомобіль) має здібності рухатися, бути керованим людиною та перевозити вантажі
class Skateboard implements Movable, Driveable
{
   ...
}
клас Skateboard (скейтборд) має здібності рухатися та бути керованим людиною

18
Задача
Java Syntax Zero,  18 рівень,  8 лекція
Недоступна
Літати чи плавати?
Літати чи плавати?

2. Ролі

Інтерфейси значно спрощують програмістам життя. Дуже часто програми містять тисячі об'єктів, сотні класів і лише кілька десятків інтерфейсів — ролей. Ролей мало, а їх комбінацій, тобто класів, — дуже багато.

Сенс у тому, що вам не потрібно писати код для взаємодії всіх класів з усіма — достатньо взаємодіяти з їхніми ролями (інтерфейсами).

Уявіть, що ви дресируєте домашніх тварин, кожна з яких може мати кілька різних здібностей. І ви посперечалися із сусідом, чиї тварини голосніше кричать. Ви просто вибираєте всіх, хто має здатність «голос», і командуєте їм: «Голос!»

Вам все одно, що це за тварини та які інші здібності вони мають. Хоч потрійне сальто назад. У цей конкретний момент вас цікавить лише здібність голосно кричати. Отакий вигляд це має в коді:

Код Опис
interface Звучання
{
   void голос();
}
Здібність Звучання. Розуміє команду голос — має відповідний метод.
class Кіт implements Звучання
{
   void голос()
   {
      println("НЯВ");
   }
}

class Собака implements Звучання
{
   void голос()
   {
      println("ГАВ");
   }
}

class Рибка
{
   ...
}
Тварини, які мають таку характеристику

Для зручності ми надали класам українські імена. Таке допускається в Java, але є вкрай небажаним.













Наша Рибка не має здібності говорити (не реалізує інтерфейс Звучання).

public static void main(String[] args)
{
   // додаємо всіх тварин до списку
   ArrayList pets = new ArrayList();
   pets.add(new Кіт());
   pets.add(new Собака());
   pets.add(new Рибка());

   // кричати, якщо є така здібність
   for(Object pet: pets)
   {
      if (pet instanceof Звучання)
      {
         Звучання крикун = (Звучання) pet;
         крикун.голос();
      }
   }
}
А як подати їм команду?

Коли кількість класів у ваших програмах досягне кількох тисяч, ви вже не зможете обійтися без інтерфейсів. Замість опису взаємодії тисяч класів досить описати взаємодію десятків інтерфейсів — це суттєво спрощує життя.

А в поєднанні з поліморфізмом — це просто бомба.


18
Задача
Java Syntax Zero,  18 рівень,  8 лекція
Недоступна
Вілларібо і Віллабаджо
Вілларібо і Віллабаджо

3. Реалізація default у методах інтерфейсів

Абстрактні класи можуть мати змінні й реалізацію методів, але множинне успадкування для них заборонено. Інтерфейси не можуть мати змінних і реалізації методів, але множинне успадкування для них дозволено.

Покажемо це у вигляді таблиці:

Здібність Абстрактні класи Інтерфейси
Змінні ✔ ✖
Реалізація методів ✔ ✖
Множинне успадкування ✖ ✔

Декому з програмістів дуже хотілося, щоб інтерфейси теж мали можливість реалізовувати методи. Можливість додати реалізацію методу не означає, що її завжди обов'язково додаватимуть. Хочеш — додавай, не хочеш — не додавай.

До того ж є проблеми із множинним успадкуванням — головним чином через змінні. У результаті вирішили — зробили. Починаючи з JDK 8 у Java з'явилася можливість додавати в інтерфейси методи з реалізацією.

Нова актуальна таблиця (для JDK 8 і вище):

Здібність Абстрактні класи Інтерфейси
Змінні ✔ ✖
Реалізація методів ✔ ✔
Множинне успадкування ✖ ✔

Тепер в абстрактних класах і в інтерфейсах можна оголошувати методи і з реалізацією, і без неї. І це чудова новина!

В абстрактних класах перед методами без реалізації потрібно додавати ключове слово abstract, а перед методами з реалізацією нічого додавати не потрібно. А в інтерфейсах все навпаки: якщо метод не має реалізації, нічого додавати не потрібно, а якщо реалізація є, потрібно додати ключове слово default.

Наведемо цю інформацію у вигляді таблички:

Здібність Абстрактні класи Інтерфейси
Методи без реалізації abstract –
Методи з реалізацією – default

Проблема

За допомогою інтерфейсів із методами можна значно спростити ієрархію багатьох класів. Наприклад, абстрактні класи InputStream і OutputStream можна оголосити інтерфейсами. Це дасть змогу використовувати їх набагато частіше й значно зручніше.

Але у світі вже написано десятки мільйонів (мільярди?) Java-класів. І якщо почати змінювати стандартні бібліотеки, то є ризик, що щось може поламатися. Навіть усе! 😛

Щоб випадково не зламати працюючі програми й бібліотеки, було вирішено, що під час успадкування реалізація методів в інтерфейсах матиме найнижчий пріоритет.

Наприклад, якщо від інтерфейсу з методом успадкувати другий інтерфейс і оголосити в ньому той самий метод, але без реалізації, то реалізація з першого методу до класу не дійде. Приклад:

interface Pet
{
   default void meow()
   {
      System.out.println("Няв");
   }
}

interface Cat extends Pet
{
   void meow(); // тут дефолтну реалізацію перекрито відсутністю реалізації
}

class Barsik implements Cat
{
}

Код не скомпілюється, тому що в класі Barsik не реалізовано метод meow().


18
Задача
Java Syntax Zero,  18 рівень,  8 лекція
Недоступна
Дорожній рух
Дорожній рух
18
Задача
Java Syntax Zero,  18 рівень,  8 лекція
Недоступна
Хто летить?
Хто летить?
Коментарі (9)
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
IronMan57
Рівень 28
17 січня 2025, 18:10
Чому б в останніх двох задачах не залишити в інтерфейсах дефолтні реалізації методів? Все одно "під час успадкування реалізація методів в інтерфейсах матиме найнижчий пріоритет." На мій погляд, можна було б залишити, наприклад у інтерфейсі Vehicle щось на зразок:
default void move() {
    System.out.println("Їду.");
}
а в класах Car і Bus, залишити реалізації, які специфічні саме для цих класів. Тоді, у випадку, коли б додавався якийсь новий клас, що також реалізує інтерфейс Vehicle, у нього відразу б з'являлась якась можливість повідомити про свій рух. А на другому етапі можна б було вже у клас додати свою специфічну реалізацію. Те ж саме з інтерфейсом Flyable. Звичайно ж, все залежить від сутності об'єктів, які моделюються цими класами. Майбуть для запуску ядерного реактора дефолтний метод не найкраще рішення.
Peace The Ball Домогосподиня в Диван у вітальні
15 листопада 2022, 22:00
Товариство, а чи є тут ще хто небудь хто пам'ятає Віллрібо і Віллабаджо? Чи то я один такий старий надумав Джаву вчити ? 🤣
Владислав Целина Team Lead в gov.auction
19 листопада 2022, 14:50
Є і ті що вміють факсом користуватися! 🙂
Anonymous #696530
Рівень 19
16 грудня 2022, 12:49
Та є.. хоч і хз що з того вийде ))
Oleksandr Java Developer
4 лютого 2023, 14:58
+1. Є.....
Василь trainee в Kindgeek
24 жовтня 2023, 18:02
37 зараз, перший раз познайомився з Java на початку 2020 року, на карантині
Olexandr
Рівень 13
4 лютого 2024, 13:50
42 зараз, не таке ще пам'ятаю))))) PS доречі - динозаврів я не застав🤣
Андрии Бумер
Рівень 41
3 жовтня 2024, 13:27
Звісно) до фака додам що є ті хто слухали плеєри на касетах, і в кого дома був телефон з дисковим набором і перший пентіум))
IronMan57
Рівень 28
17 січня 2025, 17:17
Молодь. Коли я ходив у школу, у нас на все місто (райцентр) було два комп'ютери у відділі держстатистики, а перші уроки програмування у школі були на програмованих калькуляторах.