密封的内部类
我想创建一个封闭的类的宇宙,其中每个子类是一些外部类的内部类。 我以为我可以使用密封的内部类作为层次结构的基础,如下所示:
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
的实例数据。
我发现一个解决方法是使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() } }
但是那么InnerBase
的子类就不再关闭了。
如果我正确地理解了你,你不需要像Outer
那样的实例来存储“ static
” foo
。 那么你需要的是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那样精通,所以我可能会犯错。