Перейти до основного вмісту
Модуль 4 · Урок 1 із 27/14 у курсі~15 min
Модульні уроки (1/2)

Інтерфейси

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

Це дозволяє повністю відокремити визначення операцій від їх фактичної реалізації.

Визначення інтерфейсу (interface)

Ми використовуємо ключове слово interface. Усі методи, оголошені в інтерфейсі, неявно мають значення public та abstract (це не потрібно вказувати):

Java
interface Drivable {
    void startEngine();
    void stopEngine();
}

Реалізація інтерфейсу (implements)

Клас реалізує інтерфейс за допомогою ключового слова implements і повинен забезпечити реалізацію (з тілом) для всіх визначених методів:

Java
class Motorcycle implements Drivable {
    @Override
    public void startEngine() {
        System.out.println("Rombo del motore acceso!");
    }

    @Override
    public void stopEngine() {
        System.out.println("Motore spento.");
    }
}

Переваги інтерфейсів

  1. Множинне успадкування: у Java клас може розширювати тільки один батьківський клас (єдине успадкування), але він може реалізувати кілька інтерфейсів одночасно.
    Java
    class HybridCar implements Drivable, Chargeable { ... }
  2. Відокремлення: Ви можете визначати змінні за допомогою типу інтерфейсу. Будь-який об’єкт, який реалізує цей інтерфейс, може бути призначений такій змінній.
    Java
    Drivable vehicle = new Motorcycle();
    vehicle.startEngine();

Константи в інтерфейсах

В інтерфейсах можна оголошувати поля. Ці поля неявно мають значення public static final (що означає константи класу), навіть якщо ви не вкажете ці модифікатори. Отже, вони повинні бути ініціалізовані відразу після оголошення:

Java
interface PhysicsConstants {
    double GRAVITY = 9.81; // Implicitly public static final
}

Методи за замовчуванням (default)

Починаючи з Java 8, можна визначати методи з реалізацією за замовчуванням всередині інтерфейсу за допомогою ключового слова default. Ці методи не змушують класи реалізації перевизначати їх, забезпечуючи резервну поведінку:

Java
interface Logger {
    void log(String message);

    // Default method with a body
    default void logError(String message) {
        log("ERROR: " + message);
    }
}

Спробуйте самі

вправи#java.m4.l1.e1
Спроби: 0Завантаження…

Створіть інтерфейс Flyable за допомогою методу void fly(). Потім реалізуйте клас Bird, який реалізує Flyable і друкує Flying на екрані.

Завантаження редактора…
Показати підказку

У Flyable напишіть `void fly();`. У класі Bird реалізуйте метод, позначивши його за допомогою `@Override public void fly() { System.out.println('Flying'); }`.

Рішення доступне після 3 спроб

вправи#java.m4.l1.e2
Спроби: 0Завантаження…

Визначте інтерфейс Drawable за допомогою методу void draw(). Потім реалізуйте клас Rectangle, який реалізує Drawable і друкує Drawing Rectangle.

Завантаження редактора…
Показати підказку

Визначте `void draw();` в інтерфейсі. У Rectangle використовуйте `@Override public void draw() { System.out.println('Drawing Rectangle'); }`.

Рішення доступне після 3 спроб

вправи#java.m4.l1.e3
Спроби: 0Завантаження…

Доповніть інтерфейс Swimmable, визначивши метод void swim(). Потім завершіть клас Duck, щоб він реалізував і Flyable, і Swimmable, надрукувавши Flying у методі fly() і Swimming у методі swim().

Завантаження редактора…
Показати підказку

Оголошіть `void swim();` всередині Swimmable. Оголошіть `class Duck implements Flyable, Swimmable` та реалізуйте обидва методи, друкуючи запитані рядки.

Рішення доступне після 3 спроб