#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, а затем пытаетесь переопределить его в подтипе с помощью aval name
— это недопустимо. Но это только мое понимание.4. @aarbor: Нет, сгенерированный геттер имеет другое имя, чем заданное вручную
getId
.