Sealed interfaces with hidden implementation superclasses

Vicente Romero vicente.romero at
Fri Jan 21 17:26:45 UTC 2022

Hi Mark,

On 1/4/22 08:10, Mark Raynsford wrote:
> (Apologies for the possible double post: I tried to post this to
> amber-dev@ and the message apparently never made it there. I asked
> amber-dev-owner@ but got no response there either).
> I've run across some behaviour I didn't anticipate with regards to
> sealed interfaces. I suspect that it's expected behaviour,

right this is expected behavior, if a sealed super class or super 
interface clearly defines its list of permitted subtypes, it doesn't 
make sense to define some corner case rules for which this can be 
violated depending on the accessibility of the subtypes. It could be 
that your hierarchy is not a perfect candidate to be converted to a 
sealed hierarchy or it could be that you need to cut some corners for it 
to fit into the sealed box. Just my 0.02


> but I
> feel like maybe the type system is overly constraining in this
> particular case.
> Imagine a small UI library with a sealed set of primitive components:
>    sealed interface Component permits Button, TextView, ImageView {}
>    non-sealed interface Button extends Component {}
>    non-sealed interface TextView extends Component {}
>    non-sealed interface ImageView extends Component {}
> The set of primitive components is sealed because doing so simplifies
> other parts of the system; more complex components are just aggregates
> of the primitives.
> Then, in one or more separate modules, we have some platform-specific
> implementation classes:
>    final class X11Button implements Button
>    final class X11TextView implements TextView
>    final class X11ImageView implements ImageView
>    final class QNXButton implements Button
>    final class QNXTextView implements TextView
>    final class QNXImageView implements ImageView
> This is all fine so far. The problem occurs when one of those
> implementations wants to introduce a private abstract superclass
> that contains shared implementation code but that - importantly - isn't
> actually intended to ever be observed on its own outside of the module.
> Naturally, that superclass wants to implement Component so that it can
> provide implementations of the common methods:
>    abstract class QNXComponent implements Component
>    final class QNXButton extends QNXComponent implements Button
>    final class QNXTextView extends QNXComponent implements TextView
>    final class QNXImageView extends QNXComponent implements ImageView
> The compiler (rightfully) complains that QNXComponent isn't in
> the "permits" list of Component. We can obviously remove
> the "implements Component" from QNXComponent, but this then
> means adding boilerplate @Override methods in each of QNXButton,
> QNXTextView, etc, that call the now-non- at Override methods in
> the abstract QNXComponent class.

More information about the amber-spec-experts mailing list