Sorry, I didn't find a better place to ask this. S...
# general-advice
j
Sorry, I didn't find a better place to ask this. Shouldn't a sealed class be able to implement a sealed interface?
Copy code
sealed interface Container {
 interface Foo : Container
 interface Bar : Container
}
In some other package, this is what we can get today
Copy code
sealed class BaseContainer {
   data class FooImpl(val something: Something) : Container.Foo
   object BarImpl: Container.Bar
}
With this I can't use
BaseContainer
instances as
Container
in an exhausting
when
without a explicit casting as
BaseContainer
can't implement the sealed class
Container
.
c
You have to mark the sealed class itself as inheriting the
Container
interface
Copy code
sealed class BaseContainer : Container { // <-
   data class FooImpl(val something: Something) : Container.Foo
   object BarImpl: Container.Bar
}
j
but we can't do that!
that is what I found odd, I would expect that to be allowed, but it isn't
c
Ah,
BaseContainer
is in another module?
j
in another package... but it is the same as in another module
if we don't share the package, we can't do anything
c
No, if it's in another package of the same module you should be able to inherit it,
sealed
is about modules
j
https://kotlinlang.org/docs/sealed-classes.html
Copy code
No other subclasses may appear outside the module and package within which the sealed class is defined.
🤔 1
c
Sorry, I wasn't aware it was limited to the package too. That's good to know.
But well, then it makes sense that
BaseContainer
cannot be a
Container
.
You can write
Copy code
fun BaseContainer.asContainer(): Container = when (this) {
    is BaseContainer.FooImpl -> this
    is BaseContainer.BarImpl -> this
}
Of course, it's not as clean
If I were to guess, the reason it's not automatic is that you could add another subclass to
BaseContainer
, that didn't inherit from
Container
, and that would break all code elsewhere that relied on
Container
k
I don't follow Ivan's example.
this
is a
BaseContainer
, and therefore it can't be a
BaseContatiner.FooImpl
or
BarImpl
because those two nested classes are not subclasses of
BaseContainer
.
Anyway, it seems your original question has already been answered:
Shouldn't a sealed class be able to implement a sealed interface?
Yes, indeed it can. As long as it's in the same package.
c
inside the
when
,
this
is smart-casted to
BaseContainer.FooImpl
(or
BarImpl
in the other branch), which is a valid value to return when a
Container
is expected
k
It won't work: the compiler says
Incompatible types: BaseContainer.FooImpl and BaseContainer
. Which is understandable, as there is no relationship between those two types. It's just like you can't say
if (myString is Int)
. See playground
c
Ah, I didn't notice
FooImpl
and
BarImpl
don't implement
BaseContainer
. In that case, there is no link whatsoever between them and
BaseContainer
.
My version works if you add that inheritance relationship (playground)
j
thanks, that is better than what I was doing before.