Интерфейсы
В Java невозможно множественное наследование классов. Нельзя сделать так, что есть класс Колодец, который наследует классы Постройка и Ёмкость для воды. В постройках можно прятаться, из ёмкостей можно набирать воду.
Хочется: class Well extends Building, WaterContainer
. В C++ так делать можно. Но могут возникнуть проблемы, например, проблема ромба:
Пусть class Building extends GameObject
, class WaterContainer extends GameObject
. И в GameObject
имеет метод .getType()
. Какую из реализаций унаследует GameObject?
В Java проблема решена тем, что введены Интерфейсы, они похожи на классы, но не содержат реализации методов. При создании класса можно унаследовать несколько интерфейсов.
Повторим пример про животных еще раз, только животное будет интерфейсом. interfaces
Еще раз разница между классами и интерфейсами
- в интерфейсе все методы абстрактные, т.е. не содержат тела (реализации)
- унаследоваться от нескольких классов нельзя. Зато можно унаследоваться (реализовать) несколько Интерфейсов.
- В Интерфейсе не может быть полей (обычным, статические — можно).
- В Интерфейсе могут быть статические методы.
- При использовании Интерфейса не видно его отличие от класса
- В Интерфейсе могут быть методы с реализацией по-умолчанию (default методы). Но при переопределении мы не можем вызывать реализации по-умолчанию, они совсем становятся недоступны. При переопределении метода класса можно вызвать исходную, непереопределенную версию, см. позже, слово super
Разные способы унаследоваться от класса или реализоывать интерфейс.
Пусть есть класс 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