I'd like to create a closed universe of classes, where each subclass is an inner class of some outer class. I thought I could use a sealed inner class for the base of the hierarchy, like so:
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()
}
}
}
}
Note that
Outer
is a proper class, which can have many different instances. Each instance should be able to create Inner1
's that will call the right foo
InnerBase
subclasses is finite InnerBase
has some instance method, to be used by various Inner
subclasses, which accesses Outer
's non-static method foo
InnerBase
(eg Inner1
) pass arguments to InnerBase
's constructor However, the problem with this is that I don't know how I can construct a value of type Inner1
in Outer
. I was hoping that this would work:
class Outer { // continued from above
fun someMethod() {
val x: InnerBase = InnerBase.Inner1()
}
}
but this fails with
src/InnerSealed.kt:14:27: error: unresolved reference: Inner1
val x : InnerBase = InnerBase.Inner1()
^
I guess the problem is that Inner1
is actually an inner class of Inner
, so I'd need an instance of Inner
before I could construct an instance of Inner1
. However, this is not what I'd like; I'd like Inner
to just be a base class for my Inner1
etc. classes, with some functionality which is shared between all subclasses and which access Outer
's instance data.
One workaround I've found is to make InnerBase
non- 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()
}
}
But then the subclasses of InnerBase
are no longer closed.
If I understood you correctly, you don't need instances of Outer
as much as a place to store " static
" foo
. Then you need object
s , not class
es.
I replaced class Outer
with object Outer
and removed 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()
}
}
Technically what you are trying to do is this:
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()
}
}
}
}
It provides Inner1
with an instance of Outer
without an instance of Inner
. I am not aware of any clean way of doing this in Kotlin
Maybe you are missing a static somewhere? As you don't want to instance a class to use their inner.
Granted I'm not as proficient in Kotlin so I may be horribly wrong.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.