密封的内部类

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

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是一个适当的类,它可以有许多不同的实例。 每个实例应该能够创建将调用正确的foo Inner1
  • InnerBase子类的Universe是有限的
  • InnerBase有一些实例方法,被各种Inner子类使用,访问Outer的非静态方法foo
  • InnerBase的具体子类(例如Inner1 )将参数传递给InnerBase的构造函数

但是,这个问题是我不知道如何在Outer构造一个Inner1类型的值。 我希望这会工作:

 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一个内部类,所以我需要一个Inner的实例,然后才能构造Inner1一个实例。 但是,这不是我想要的; 我想Inner只是我的Inner1等类的基类,其中一些功能是在所有子类之间共享的,并且访问Outer的实例数据。

我发现一个解决方法是使InnerBasesealed

 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() } } 

但是那么InnerBase的子类就不再关闭了。

如果我正确地理解了你,你不需要像Outer那样的实例来存储“ staticfoo 。 那么你需要的是object ,而不是class

我用class Outer object Outer替换了class 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() } } 

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

 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提供了一个没有Inner实例的Outer实例。 我不知道在Kotlin做这个干净的方式

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

当然,我并不像Kotlin那样精通,所以我可能会犯错。