Что такое default-метод в интерфейсе Java и для чего он нужен?

Ответ

Default-метод (метод по умолчанию) — это метод в интерфейсе Java, имеющий собственную реализацию. Он был добавлен в Java 8 для решения проблемы обратной совместимости при расширении интерфейсов.

Основное назначение:

  • Позволяет добавлять новую функциональность в существующие интерфейсы, не ломая код всех классов, которые их уже реализуют.
  • Класс-реализатор может использовать реализацию по умолчанию, переопределить её или объявить метод как abstract (если класс сам является абстрактным).

Пример:

interface Vehicle {
    void start(); // Абстрактный метод

    // Default-метод с реализацией
    default void honk() {
        System.out.println("Beep beep!");
    }
}

class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car started");
    }
    // Метод honk() не обязан быть переопределен
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.start(); // Car started
        car.honk();  // Beep beep! (вызывается default-реализация)
    }
}

Ключевые особенности:

  • Объявляется с ключевым словом default.
  • Может вызывать другие методы того же интерфейса.
  • Не может переопределять методы класса Object (например, toString, equals).
  • Разрешает множественное наследование поведения (но не состояния), что было невозможно до Java 8.

Ответ 18+ 🔞

Да, блядь, вот это тема! Слушай сюда, сейчас разжую, как это работает, а то некоторые до сих пор думают, что интерфейс — это только контракт с пустыми методами. Ну, типа, подпишись и иди сам всё делай, мудила.

Так вот, в Java 8 придумали default-методы, и это, на самом деле, ёперный театр по удобству. А зачем? А представь, блядь, ты — создатель какого-нибудь старого, уважаемого интерфейса List. И тебе вдруг захотелось добавить туда новый метод, например, sort(). И что, по-твоему? Ты его добавил, а все программисты, которые твой интерфейс реализовывали в своих MySuperArrayList, должны срочно бежать и дописывать реализацию этого sort(), иначе у них всё сломается? Да нихуя! Это ж пиздец какой-то, обратной совместимости ноль, ебать.

Вот чтобы не быть таким мудаком, и придумали default-методы. Это методы в интерфейсе, у которых уже есть тело, ёбаная реализация! И объявляются они через слово default. Класс, который реализует интерфейс, может спокойно пользоваться этой готовой реализацией, как будто так и было. А может, если он недоволен, её переписать на свой лад. Или вообще проигнорировать — хуй с ним.

Смотри, вот тебе живой пример, чтобы не быть голословным:

interface Vehicle {
    void start(); // Вот это классика, абстрактный метод. Реализуй, сынок, или иди нахуй.

    // А вот это новшество, блядь! Готовая реализация, бери и пользуйся.
    default void honk() {
        System.out.println("Beep beep!");
    }
}

class Car implements Vehicle {
    @Override
    public void start() {
        System.out.println("Car started");
    }
    // А метод honk() я тут даже не упоминаю! Он у меня автоматом сработает из интерфейса.
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.start(); // Выведет: Car started
        car.honk();  // Выведет: Beep beep! Всё само, магия, блядь!
    }
}

А теперь главные фишки, которые надо запомнить, чтобы не облажаться:

  1. Ключевое слово default. Без него — абстрактный метод, с ним — готовый, с телом. Запомни, ебушки-воробушки.
  2. Может звать другие методы интерфейса. Внутри default-метода ты спокойно можешь вызывать другие методы того же интерфейса, даже абстрактные (но это уже опасные игры).
  3. Не лезь к Object! Ты не можешь в интерфейсе сделать default-реализацию для toString(), equals() или hashCode(). Это методы класса Object, и Java сама решит, кто тут главный. Не выёбывайся.
  4. Множественное наследование поведения. Вот это, блядь, самое интересное! Раньше от двух классов унаследоваться было нельзя. А от двух интерфейсов с default-методами — запросто! Только если у них будут методы с одинаковой сигнатурой, то придётся явно выбрать, какой вызывать, или написать свою реализацию, иначе компилятор скажет: «Чувак, бля, я нихуя не понимаю, что ты от меня хочешь».

Короче, default-методы — это мощный инструмент, чтобы расширять старые интерфейсы, не разнося вдребезги весь существующий код. Умная штука, хоть и добавляет головной боли с разрешением конфликтов. Но без этого никуда, прогресс, блядь, не остановить.