密封的内部阶级

时间:2016-11-19 08:49:40

标签: java inheritance scope kotlin inner-classes

我想创建一个封闭的类世界,其中每个子类都是某个外部类的内部类。我以为我可以使用密封的内部类作为层次结构的基础,如下所示:

class Outer {
    fun foo(): Int {
        // ...
    }

    inner sealed class InnerBase(val i: Int) {
        fun sharedFunctionality() {
            println(foo() + i)
        } 

        abstract fun doIt()

        inner class Inner1: InnerBase(1) {
            override fun doIt() {
                blah()
                sharedFunctionality()
                bloo()
            }
        }
    }
}

请注意

  • Outer是一个合适的类,可以有许多不同的实例。每个实例都应该能够创建Inner1来调用正确的foo
  • InnerBase子类的范围是有限的
  • InnerBase有一些实例方法,供各种Inner子类使用,它们访问Outer的非静态方法foo
  • InnerBase的具体子类(例如Inner1)将参数传递给InnerBase的构造函数

然而,问题是我不知道如何在Inner1中构建Outer类型的值。我希望这会奏效:

class Outer { // continued from above
    fun someMethod() {
        val x: InnerBase = InnerBase.Inner1()
    }
}

但是

失败了
src/InnerSealed.kt:14:27: error: unresolved reference: Inner1
    val x : InnerBase = InnerBase.Inner1()
                                 ^

我想问题是Inner1实际上是Inner的内部类,所以在构造{{1}的实例之前我需要一个Inner的实例}。但是,这不是我想要的;我希望Inner1只是我的Inner等类的基类,其中一些功能在所有子类之间共享,并且访问Inner1的实例数据。

我发现的一个解决方法是Outer非 - InnerBase

sealed

但是class Outer { fun foo(): Int { // ... } inner abstract class InnerBase(val i: Int) { fun sharedFunctionality() { println(foo() + i) } abstract fun doIt() } inner class Inner1: InnerBase(1) { override fun doIt() { sharedFunctionality() } } fun someMethod() { val x : InnerBase = Inner1() } } 的子类不再关闭。

3 个答案:

答案 0 :(得分:1)

如果我理解正确,您不需要Outer的实例与存储“staticfoo的地方一样多。那么您需要object s,而不是class es。

我将class Outer替换为object Outer并删除了sealed

object Outer {
    var foo = 42

    sealed class Inner(val i: Int) {
        init {
            println(foo + i)
        }

        class Inner1: Inner(1)
    }

    init {
        val x: Inner = Inner.Inner1()
    }
}

答案 1 :(得分:1)

从技术上讲,你要做的是:

class Outer {
    var foo = 42
    init {
        val x: InnerBase = InnerBase.Inner1(this)
    }

    sealed class InnerBase(val outer: Outer, val i: Int) {

        fun sharedFunctionality() {
            println(outer.foo + i)
        } 

        abstract fun doIt()

        class Inner1(outer: Outer): InnerBase(outer, 1) {
            override fun doIt() {
                sharedFunctionality()
            }
        }
    }
}

它为Inner1提供了Outer的实例,但没有Inner的实例。我不知道在Kotlin中有任何干净的方法

答案 2 :(得分:0)

也许你错过了一个静态的地方?因为你不想让一个类使用它们的内部。

当然,我对Kotlin并不那么精通,所以我可能会非常错误。