簡體   English   中英

在Kotlin的密封課程之外引用?

[英]Reference outside the sealed class in Kotlin?

我正在嘗試創建一個類,該類使用其自己的狀態對持有引用的外部對象的狀態進行操作。 外部對象可以是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替換sealed
  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}"
}

(或者,將BoxABoxB移出ABTool范圍,而不是將AB標記為內部)

一種替代方法是將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 畢竟,那才是inner真正所做的。

在此特定情況下,該字段恰好在AB本身中未使用,因此您可以從那里將其刪除並在BoxABoxB val

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM