Использование функции по умолчанию для интерфейса в Kotlin

У меня есть интерфейс Kotlin с реализацией по умолчанию, например:

interface Foo {
    fun bar(): String {
        return "baz"
    }
}

Это будет нормально, пока я не попытаюсь реализовать этот интерфейс с Java. Когда я это делаю, он говорит, что класс должен быть помечен как абстрактный или реализовать метод bar(). Также, когда я пытаюсь реализовать метод, я не могу вызвать super.bar().

Ответ 1

Пожалуйста, смотрите связанную проблему.

В комментариях есть рекомендация:

Напишите ваш интерфейс на Java (с методами по умолчанию), и классы Java и Kotlin правильно используют эти значения по умолчанию

Ответ 2

Генерация истинных методов по default вызываемых из Java, является экспериментальной функцией Kotlin 1.2.40.

Вам нужно аннотировать методы с @JvmDefault аннотации @JvmDefault:

interface Foo {
    @JvmDefault
    fun bar(): String {
        return "baz"
    }
}

Эта функция по-прежнему отключена по умолчанию, для ее работы необходимо передать -Xjvm-default=enable компилятору. (Если вам нужно сделать это в Gradle, смотрите здесь).

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

Ответ 3

В отличие от более ранней версии Java8, Kotlin может иметь реализацию по умолчанию в интерфейсе.

При внедрении интерфейса Foo в класс Java. Kotlin скрывает эту реализацию интерфейса. Как указано здесь.

Массивы используются с примитивными типами данных на платформе Java, чтобы избежать затрат на операции бокса/распаковки. Поскольку Kotlin скрывает эти детали реализации, требуется обходное решение для взаимодействия с Java-кодом.

Это специфично для массивов в приведенной выше ссылке, но также применимо ко всем классам (может быть, для поддержки более ранней версии Java8).

ИЗМЕНИТЬ

Выше объяснение основано на мнениях.

Одна вещь, с которой я столкнулся, и это главная причина.

Двоичные файлы Kotlin были скомпилированы с использованием java-байт-кода версии 1.8 без стандартных методов в интерфейсах. И они сталкиваются с решающей проблемой, которая ее решает.