Зарегистрируйтесь, чтобы продолжить обучение

Интерфейсы Java: Введение в ООП

Интерфейсы

Классы в Java — основы основ, но их описание будет неполным без интерфейсов, с которыми они тесно связаны. Интерфейсы — более простая конструкция, но, как и в случае с классами, полное понимание интерфейсов требует опыта работы с ними. Зачем они нужны? Интерфейсы позволяют задавать требования к классам, то есть какие методы требуются от класса. Предположим, что мы хотим работать в приложении с генератором паролей. Генератор в нашем случае это обычный класс, с методом generate(), возвращающим пароль.

var generator = new SimplePasswordGenerator();
generator.generate(); // Возвращает готовый пароль
generator.generate(); // Уже другой пароль

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

Создадим интерфейс PasswordGenerator и опишем в нем два метода generate(). Один метод будет без параметров, другой — с возможностью настройки длины пароля:

interface PasswordGenerator {
    String generate();
    String generate(int length);
}

Теперь интерфейс нужно реализовать. Делается это в определении класса:

// Ключевое слово implements означает, что класс реализует интерфейс PasswordGenerator
class SimplePasswordGenerator implements PasswordGenerator {
    public String generate() {
        // Обращаемся к методу объекта
        // 16 – выбранное значение по умолчанию
        return this.generate(16);
    }

    public String generate(int length) {
        // Тут логика генерации простого пароля
    }
}

Интерфейсы не ограничивают класс в его расширении. Помимо интерфейсных методов, мы можем добавить и любые другие.

Но все таки одно ограничение есть. Если класс применяет интерфейс, то он должен реализовывать все методы, указанные в интерфейсе, причем именно так, как они описаны.

В чем же суть интерфейсов? Если коротко: полиморфизм, а если точнее — полиморфизм подтипов (subtyping). Прямо сейчас он нам не очень нужен, но для общего развития попробуем ухватить его идею.

Осторожно, дальнейший текст может напугать. Если он кажется вам сложным, просто пропустите, все это мы будем повторять еще не раз.

Код, который будет использовать passwordGenerator может выглядеть так:

class UserController {
    // Здесь создаются пользователи
    // Этот код вызывается где-то внутри приложения при регистрации пользователя
    public void create() {
        // Создаем пользователя
        // И где-то тут же генерируем ему пароль
        var generator = new SimplePasswordGenerator();
        var password = generator.generate();
    }
}

Неплохой код, но представьте, что класс может меняться без изменения кода, просто в зависимости от того, какие опции выбирает пользователь при генерации пароля. Вполне реальная ситуация. Самый простой способ реализовать такую схему — вставить условие на параметр, который вводит пользователь. В одном случае берем один класс, в другом другой.

var generator;
if (userChooseSomething) {
    generator = new SimplePasswordGenerator();
} else {
    generator = new SuperPasswordGenerator();
}

Такой код уже может стать проблемой, если генераторы будут постоянно добавляться. Ситуация ухудшится, когда эта конструкция начнет расползаться по разным частям проекта. Интерфейсы изящно решают такие ситуации.

Сделаем так, чтобы класс SuperPasswordGenerator() тоже реализовывал интерфейс PasswordGenerator:

class SuperPasswordGenerator implements PasswordGenerator {
    public String generate() {
        return this.generate(16);
    }

    public String generate(int length) {
        // Тут уже другая логика генерации супер-сложного пароля
    }
}

Код, который будет использовать PasswordGenerator, меняется на такой:

class UserController {
    // Интерфейс = Тип
    // Вместо конкретного класса указываем интерфейс
    public void create(PasswordGenerator generator) {
        var password = generator.generate();
    }
}

Интерфейсы в Java — это настоящие типы данных, поэтому их можно указывать в определениях методов.

В коде выше видно, что мы требуем передавать в метод create тип PasswordGenerator. Таким типом будет любой объект, класс которого реализует интерфейс PasswordGenerator. Теперь мы можем передать в метод create() любой генератор паролей, который реализует интерфейс PasswordGenerator. В получившемся коде генератор создается не там, где используется. Он создается где-то раньше, а уже в код приходит нужная реализация.

Таким образом мы можем получить разное поведение, не меняя сам код, который использует PasswordGenerator.

https://replit.com/@hexlet/java-oop-basics-intrfaces

Все это уже станет актуальным, как только мы дойдем до Java-коллекций.

Соглашения и правила

К интерфейсам предъявляются такие же требования как и к классам

  1. Один файл – один интерфейс. Имя файла и интерфейса совпадают.
  2. Интерфейсы начинаются с заглавной буквы.

Дополнительные материалы

  1. Интерфейсы. Официальная документация

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 25 000 ₸ в месяц
Разработка приложений на языке Java
10 месяцев
с нуля
Старт 26 декабря

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»