在 Kotlin 中密封 class 之外的引用?

Reference outside the sealed class in Kotlin?

我正在尝试创建一个 class,它使用自己的状态来操作它引用的外部对象的状态。外部对象可以是classA或B,两者类似,但不受作者控制。因此,根据 .

创建了一个密封的 class 来访问它们的共同属性
// *** 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}"
}

现在的问题是我发现我不能按照我想要的方式操作外部对象,因为密封的 class 不能引用它的外部 class成员。有没有更好的方法来完成这项工作,即使使用不同的方法(除了密封 class),同时:

对此或类似解决方法有任何想法吗?也许是我还没有想到的更实用的方法?

如果ABTool被密封class是你可以放弃的东西,那么这里有一个解决方案:

  1. ABTool 声明处将 sealed 替换为 inner abstract
  2. 同时将 BoxABoxB 标记为 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 标记为内部,而是将 BoxABoxB 移出 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
  }
}

并在从 ABTool 创建时传递 this。毕竟,这正是 inner 真正做的事情。

在这种特定情况下,该字段恰好在 AB 本身未使用,因此您可以从那里删除它并在 BoxABoxB 中将其设为 val .