Сколько методов может быть в функциональном интерфейсе

Ответ

Функциональный интерфейс в Java должен содержать ровно один абстрактный метод (SAM — Single Abstract Method). Однако, он может включать:

  • Любое количество default методов.
  • Любое количество static методов.
  • Методы, унаследованные от Object (например, toString(), equals()), они не считаются.

Пример:

@FunctionalInterface
interface Calculator {
    int calculate(int a, int b); // единственный абстрактный метод

    default void logResult(int result) {
        System.out.println("Result: " + result);
    }

    static String getVersion() {
        return "1.0";
    }
}

Ответ 18+ 🔞

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

Представь себе такую ситуацию. Ты приходишь в бар и говоришь: «Мне пиво». Это один абстрактный метод. Ты можешь ещё сказать: «И дайте мне стакан, он у вас тут на стойке стоит» — это static метод, он общий для всех. А можешь добавить: «А ещё налейте мне в этот стакан, я сам не буду идти» — это default метод, у тебя уже есть какая-то реализация по умолчанию. Но заказ-то, суть — один: «Мне пиво». Вот и весь SAM — Single Abstract Method. Один абстрактный метод, ёпта. Всё остальное — это уже довески, буфера всякие.

И главное, что часто вводит в ступор — методы от Object. Ну, toString() или equals(). Так вот, их можно не считать! Серьёзно, они как будто не в зачёт. Потому что они и так у всех есть, они как воздух. Интерфейс говорит: «Да похуй, пусть будут, мне от этого не тесно». Главное, чтобы твой собственный, уникальный абстрактный метод был один. Как тот самый заказ в баре.

Вот смотри на этот пример, тут всё как на ладони:

@FunctionalInterface
interface Calculator {
    int calculate(int a, int b); // вот он, единственный абстрактный метод, звезда вечера

    default void logResult(int result) {
        System.out.println("Result: " + result);
    } // default метод — типа «а ещё сделай вот это, но если что, я уже написал как»

    static String getVersion() {
        return "1.0";
    } // static метод — общая утилита, как открывалка для всех на столе
}

Аннотация @FunctionalInterface — это вообще ядрёна вошь. Она тебе не даст случайно насрать в код и добавить второй абстрактный метод. Компилятор посмотрит и такой: «Чувак, ты чего творишь? Ты же функциональный интерфейс объявил, а абстрактных методов тут овердохуища!». И не скомпилирует. Красота же.

Так что запомни: один главный метод — это святое. Всё остальное — это просто возможность не быть уж совсем тупым куском интерфейса, а иметь какую-то полезную обвязку. Удивление пиздец, но это действительно удобно.