Недвижимость в интерфейсе не может иметь поле подкладочный

Я изучаю Котлин . Мой код выглядит следующим образом:

interface BaseLogicDecoupler<A : BaseViewNotifier, B : BaseScreenRouter> { var notifier: A? var router: B? fun attachNotifier(notifier: A?) { this.notifier = notifier } fun detachNotifier() { notifier = null; } fun attachRouter(router: B?) { this.router = router } fun detachRouter() { router = null; } } 

Но когда я меняю его и пытаюсь предоставить аксессуар для свойства вроде следующего:

 var notifier: A? get() = notifier 

Он не компилируется с ошибкой: « Свойство в интерфейсе не может иметь поля поддержки .

Из документа doc здесь интерфейсы kotlin могут обеспечить реализацию и могут иметь свойства с помощью аксессуаров. Почему компиляция терпит неудачу?

Я не могу понять ошибку. Что он говорит? Может ли кто-нибудь объяснить в простых выражениях?

Это неожиданный угловой случай, который вам подходит, чтобы найти его.

Позвольте мне вкратце объяснить, что происходит. Для простоты я использую разделенный интерфейс A и класс B :

 interface A { var notifier: Int } 

Обычно свойство var в классе включает в себя 3 компонента: частное backing field для хранения его значения, метод setter для его записи и метод getter для его чтения. Но у интерфейса не может быть поля (потому что живое – это боль, а математика не складывается, если это так), поэтому свойство var в интерфейсе включает только 2 компонента: setter и getter .

Как я изложил выше, наш интерфейс A объявил 2 метода: setter и getter , оба без реализации. Давайте добавим к нему некоторые реализации:

 interface A2 { var notifier: Int get() {return 1} set(v) {} } 

Все идет нормально. Два open метода с реализациями, а не из них – любые поля. Но что, если объявлена ​​только одна из реализаций?

 interface A3 { var notifier: Int //ERROR: Property in an interface cannot have a backing field get() {return 1} //set(v) {} } 

Оказывается, если вы укажете только getter , Kotlin также генерирует (default) setter для свойства. Другими словами, A3 здесь похож на A4 :

 interface A4 { var notifier: Int get() {return 1} set(v) {field = v} //Obviously an error } 

Это может быть ошибка или предполагаемое поведение. Вот билет для справки : https://youtrack.jetbrains.com/issue/KT-15193

Возможные обходные пути:

  • объявить адекватный сеттер, как в A2
  • используйте abstract class вместо интерфейса
Intereting Posts
Передача списка объектов в фрагмент ошибка в аннотациях kotlin? демо-версия kotlin realm Не удается найти целевое тело после запуска Jfinal веб-приложения с kotlin В Kotlin почему аргумент по умолчанию не передается после того, как функция назначается переменной? Элементы представления Android NavigationView Headerlayout не запускают события щелчка Есть ли еще более простой способ выражения анонимных классов в Котлине? Как мне выполнить компиляцию пакетов в Maven? Библиотека Android, написанная в Kotlin, обеспечивает поддержку Java-приложений Как я могу условно добавить асинхронную операцию в середине потока RxJava? Почему Kotlin позволяет иметь два класса с одинаковым именем и пакетом в разных папках (например, main и androidTest)? Kotlin Exposed не совершает транзакции Когда нам нужны файлы * .meta.js в Котлине? Аннотации к классам файлов Как сделать работу @Autowired в обычном классе?