Intereting Posts
Как отобразить уведомление в приложении, которое не хранится в ящике уведомлений à la Snapchat kodein, ввод данных в простой класс Как использовать тип перечисления Postgresql через Kotlin Exposed ORM? Почему проверка ссылочного равенства возвращает true, когда ссылка различна Есть ли у Котлина «характер»? Anko – Установка значения строки и столбца для элемента в gridLayout Мне нужно знать, почему? и если я изменю эту строку на "println (name + two)" ошибка решена? Spring Boot 2.0.0.M7, Kotlin, Gradle – bean не удалось найти латинит, ленивый и одноэлементный узор в котлине Множественная переменная let в Kotlin В Kotlin, как я могу создать экземпляр класса с использованием собственного параметра java? Как синтетически добавить активность в задний стек перед началом другого? Как установить стоимость недвижимости в Котлине Какой метод используется в Double.toInt () Kotlin, округление или усечение? Является ли формат данных, хранящихся в kotlin.MetaData документированы где угодно?

Ссылка за закрытым классом в Котлине?

Я пытаюсь создать класс, который использует свое собственное состояние для работы с состоянием внешнего объекта, на который он ссылается. Внешний объект может быть класса A или B, которые аналогичны, но не контролируются автором. Таким образом, запечатанный класс создается для доступа к их общим атрибутам, за этот более ранний ответ от @ SimY4 .

// *** DOES NOT COMPILE *** class A { // foreign class whose structure is not modifiable val prop get()= "some string made the Class-A way" } class B { // foreign class whose structure is not modifiable val prop get()= "some string made the Class-B way" } data class ABTool (val obj:AB, val i:Int, val j:Int) { // class that manipulates i and j and uses them to do // things with AB's "common" attributes through the sealed class AB sealed class AB { // substitute for a common interface abstract val prop: String abstract val addmagic: String data class BoxA(val o:A) : AB() { override val prop get()= o.prop override val addmagic get() = prop + this@???.magic // HOW TO REFERENCE? } data class BoxB(val o:B) : AB() { override val prop get()= o.prop override val addmagic get() = this@???.magic + prop // HOW TO REFERENCE? } } val magic get()= "magic: ${i*j}" } 

Проблема в том, что я понял, что я не могу работать с внешним объектом так, как хочу, потому что запечатанный класс не может ссылаться на его внешних членов класса. Есть ли лучший способ сделать эту работу, даже если используется другой подход (кроме закрытого класса), а:

  • не изменяя иностранные классы A или B;
  • учитывая, что A и B (и многие другие в реальном случае) похожи, поэтому я пытаюсь написать один инструмент, который вычисляет и добавляет магию к A и B с той же базой кода; а также
  • отметив, что хотя инструменты ABTool одинаковы, то, как они применяются для добавления магии, несколько отличается от A и B, так как доступ к концептуально общим элементам A и B может быть другим.

Любые мысли об этом или подобном обходном пути? Может быть, более функциональный подход, который я еще не задумал?

Если ABTool является закрытым классом, вы можете отказаться от него, то вот решение:

  1. Заменить ABTool на inner abstract ABTool декларации ABTool ;
  2. Mark BoxA и BoxB являются inner ;
 data class ABTool(val obj: AB, val i: Int, val j: Int) { inner abstract class AB { abstract val prop: String abstract val addmagic: String inner class BoxA(val o: A) : AB() { override val prop get() = o.prop override val addmagic get() = prop + magic } inner class BoxB(val o: B) : AB() { override val prop get() = o.prop override val addmagic get() = magic + prop } } val magic get() = "magic: ${i * j}" } 

(вместо того, чтобы маркировать AB как внутренний, переместите BoxA и BoxB из него в область ABTool )

Альтернативой было бы добавить поле ABTool в AB :

 sealed class AB(val tool: ABTool) { abstract val prop: String abstract val addmagic: String data class BoxA(val o:A, tool: ABTool) : AB(tool) { override val prop get()= o.prop override val addmagic get() = prop + tool.magic } data class BoxB(val o:B, tool: ABTool) : AB(tool) { override val prop get()= o.prop override val addmagic get() = tool.magic + prop } } 

и передать this при создании из ABTool . В конце концов, это то, что действительно на самом деле.

В этом конкретном случае поле не используется в самом AB , поэтому вы можете удалить его оттуда и сделать его val в BoxA и BoxB .