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

Thanks,
Vicente

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-@Override methods in
the abstract QNXComponent class.


Reply via email to