Kotlin Расширяет Класс Java — Абстрактный Метод Getter Не Реализован

#java #kotlin

Вопрос:

Рассмотрим, что у вас есть следующий класс в java

 public abstract class Base {
    public abstract Integer getId();
}
 

Затем вы хотите начать добавлять Kotlin в свой проект, поэтому вы создаете ребенка этого класса в Kotlin

 class Child(var id: Int? = null) : Base() {

}
 

Как вы это делаете? При определении Child , как указано выше, вы получаете ошибку Class 'Child' is not abstract and does not implement abstract base class member public abstract fun getId(): Int! defined in Base

Если вы определите это в теле вместо этого:

 class Child() : Base() {
    var id: Int? = null
}
 

Вы получаете исключение Accidental override: The following declarations have the same JVM signature (getId()Ljava/lang/Integer;): public final fun <get-id>(): Int? defined in Child public abstract fun getId(): Int! defined in Child

Похоже, вы не можете использовать имя свойства id , так как оно противоречит имени абстрактного метода. Есть ли какое-либо обходное решение для этого?

Ответ №1:

Вы можете заставить его работать, хотя это немного сложно.

 class Child() : Base() {
    @get:JvmName("_getId") // any other name will do
    var id: Int? = null

    override fun getId(): Int? = id
}
 

Комментарии:

1. Интересный… есть мысли, зачем это нужно? Я думаю, вы также можете сделать @JvmField id это, а затем определить геттер /сеттер самостоятельно.

2. Кроме того, разве сгенерированная подпись получателя не совпадает с той, которую вы определили вручную? Кажется странным, что это не сработало бы из коробки

3. Я думаю, дело в том, что вы не можете переопределить функцию с помощью свойства. Даже если переопределяемая функция явно является получателем, а свойства в основном являются получателями/установщиками. Это то же самое, если вы создаете fun getId() в Kotlin, а затем пытаетесь переопределить его в подтипе с помощью a val name — это недопустимо. Но это только мое понимание.

4. @aarbor: Нет, сгенерированный геттер имеет другое имя, чем заданное вручную getId .