Is there any possibility to extend sealed class/in...
# getting-started
e
Is there any possibility to extend sealed class/interface in other package? What I’m trying to achieve is to make some sort of inheritance. For example I have several MVI stores, declaring their possible output as
Copy code
sealed interface Label {
    ...
    data object NoConnection: Label
    data object TechnicalError: Label
}
All this stores should contain some subset of children (in this example
NoConnection
and
TechnicalError
). So I would like to do something like this:
Copy code
sealed interface BaseErrorHandlingLabel {
        data object NoConnection: BaseErrorHandlingLabel
        data object TechnicalError: BaseErrorHandlingLabel
    }

    sealed interface Label extends BaseErrorHandlingLabel {
        data object CustomA: Label
        data object CustomB: Label
    }
and get
NoConnection
and
TechnicalError
included in each inherited interface. I didn’t find any way to to that in Kotlin right now and have to duplicate this logic in each sealed class/interface. Am I missing something?
h
Isn't the entire point of
sealed
to remove the possibility of extending?
e
I would say the entire point of
sealed
is to make it possible to do exhaustive
when
check with compile-time errors. Extending doesn’t violate this idea. If you make
when
for the
BaseErrorHandlingLabel
you will have only 2 possible values. And if you make
when
for the
Label
you will have 2 options from the base class + children. It is similar to class inheritance, when you don’t see additional functions/fields if you use reference to a parent class, but if you use the child it is possible to use both parent’s and his own members.
k
You can't extend a sealed class/interface in a different package. However, your example code extends an interface in the same package, so that's not the issue here. I'm not quite sure what problem you're trying to describe. In your code,
NoConnection
and
TechnicalError
both implement
Label
which is the sub-interface. So if you created another sub-interface, say
sealed interface AnotherLabel : BaseErrorHandlingLabel
you wouldn't be able to use
NoConnection
and
TechnicalError
because they are
Label
, and not
AnotherLabel
.
e
@Klitos Kyriacou sorry, it was a typo, fixed the base type for
No Connection
and
TechnicalError
. In real life this 2 interfaces are not in the same package. I can have many features in different packages and modules and I would like to use same set of pre-configured items in them, defined in one core module.
o
As @Klitos Kyriacou mentioned and according to the kotlin documentation for
sealed
classes/interfaces, it is not possible to extend from different package, see
k
Thanks for the clarification. Even if they were in the same package, the inheritance hierarchy doesn't work:
Copy code
BaseErrorHandlingLabel <-- NoConnection
                       <-- TechnicalError
                       <-- Label <-- CustomA
                                 <-- CustomB
So an exhaustive
when
for
Label
would require only
CustomA
and
CustomB
. No instance of
Label
can ever be
NoConnection
or
TechnicalError
because they're not
Label
. It seems what you are looking for is a way to say, "every sub-interface of this interface includes the following classes as though they were defined in the subinterface itself".
e
Yes, you are correct - I can’t do that. But I don’t see any semantic problems in this approach.
d
I think you would need the union type, i.e. the union of BaseErrorHandlingLabel and Label. I'm not sure whether the spec draft would cover this use case.
e
@David Kubecka what is it?
d