Интерфейсы

В Java невозможно множественное наследование классов. Нельзя сделать так, что есть класс Колодец, который наследует классы Постройка и Ёмкость для воды. В постройках можно прятаться, из ёмкостей можно набирать воду.

Хочется: class Well extends Building, WaterContainer. В C++ так делать можно. Но могут возникнуть проблемы, например, проблема ромба:

Пусть class Building extends GameObject, class WaterContainer extends GameObject. И в GameObject имеет метод .getType(). Какую из реализаций унаследует GameObject?

В Java проблема решена тем, что введены Интерфейсы, они похожи на классы, но не содержат реализации методов. При создании класса можно унаследовать несколько интерфейсов.

Повторим пример про животных еще раз, только животное будет интерфейсом. interfaces

Еще раз разница между классами и интерфейсами

Разные способы унаследоваться от класса или реализоывать интерфейс.

Пусть есть класс A, и вы хотите сделать наследника … extends A (для интерфейса аналогично, implements A)

Способ 1. Создать полноценный класс, который расширяет или реализует A.

В файле B.java пишем public class B extends A

Способ 2. Анонимный класс. Можно реализовать класс прямо в коде, в момент создания объекта:

A a = new A() {
    //внутри этих скобок можно реализовать наследника A
};

См. cow в примере про животных.

Способ 3. Лямбда-выражение.

Аналог lambda x: x + 1 в Python.

Если интерфейс имеет ровно один метод (default методы не считаются), то можно реализовывать этот интерфейс лямбда-выражением.

Отдельный пример: lambdas