Основная проблема становится видимой, если вы удалите @JvmField
;если вы удалите его из BaseDelegate, то получите там ту же ошибку.
То, что происходит, - поле создает свои собственные методы получения и установки, которые конфликтуют с методами в родительском классе.Использование @JvmField в производном классе не работает;это все еще показывает ту же ошибку.
Итак, вместо объявления геттеров и сеттеров, существует относительно простое решение.Интерфейсы в Kotlin могут иметь поля.Как бы то ни было, они скомпилированы для получателей и установщиков из того, что я могу сказать.В любом случае, главное в том, что он позволяет легко работать с необходимыми переменными в интерфейсах.
Итак, измените ваш интерфейс следующим образом:
interface ViewDelegate {
var clickHandler: View.OnClickListener
fun getDataType() : String
fun getItemViewType() : Int
fun onCreateViewHolder(parent: ViewGroup): RecyclerView.ViewHolder
fun onBindViewHolder(holder: RecyclerView.ViewHolder, data: ClipData.Item, position: Int)
}
Обратите внимание, что я удалил геттерыи установщики, и просто заменили его на переменную.
Теперь, в классе BaseDelegate, вы должны переопределить переменную:
class BaseDelegate(override var clickHandler: View.OnClickListener) : ViewDelegate
@ JvmField ушел.Также не забудьте удалить свой метод получения и установки в классе, они вам больше не понадобятся.После удаления @JvmField, метод получения и установки в BaseDelegate и ViewDelegate, в дополнение к добавлению поля, должен скомпилироваться.
Поскольку вы не можете изменить интерфейс (кстати, это лучший вариант, который у вас есть), есть еще один вариант.Закрытые поля не используют методы получения и установки, если они не определены явно.Возьмите этот пример:
class Test(){
var x: Int = 0
fun something(){
x = 3
}
}
Он компилируется в:
public final class Test {
private int x;
public final int getX() {
return this.x;
}
public final void setX(int var1) {
this.x = var1;
}
public final void something() {
this.x = 3;
}
}
Обратите внимание на прямую ссылку на x.Теперь, если я сделаю это приватным:
class Test(){
private var x: Int = 0
fun something(){
x = 3
}
}
Это произойдет:
public final class Test {
private int x;
public final void something() {
this.x = 3;
}
}
Получатель и установщик исчезли.Однако, если я явно объявлю их:
class Test(){
private var x: Int = 0
get() = field
set(v) {
field = v;
}
fun something(){
x = 3
}
}
Он выдаст:
public final class Test {
private int x;
private final int getX() {
return this.x;
}
private final void setX(int v) {
this.x = v;
}
public final void something() {
this.setX(3);
}
}
То же самое происходит с общедоступной переменной;если получатель объявлен и он настроен (не просто get set
), он использует .setX(v)
вместо this.x = v
.
Как это применимо к вашей ситуации?
Вы столкнулисьобъявления сгенерированного геттера и геттера, объявленного библиотекой.Итак, поскольку приватные поля не создают геттер и / или сеттер, если они не определены явно, измените ваш var на приватный:
open class BaseDelegate(private var clickHandler: View.OnClickListener) : ViewDelegate
Обратите внимание, что это нарушает синтаксис доступа к свойству; вы не сможете звонить derivedViewDelegateInst.clickHandler
, и вам нужно будет использовать геттер даже в Котлине.