Possible refinement for sealed classes

Brian Goetz brian.goetz at oracle.com
Thu Apr 1 13:23:28 UTC 2021


Been working with sealed classes a lot lately, and have run into a 
pattern that we might want to consider supporting more directly, which 
is interfaces that exist solely to refine a sealed class or interface. 
Suppose we have:

     sealed abstract class Sandwich { }

     interface WithCheese { }
     interface Toasted { }
     interface NontraditionalStructure { }
     interface NontraditionalIngredients { }

     class Cheeseburger extends Sandwich implements WithCheese { }

     class TunaMelt extends Sandwich implements Toasted, WithCheese { }

     class Burrito extends Sandwich implements WithCheese, 
NontraditionalStructure { }

     class ChipButty extends Sandwich implements 
NontraditionalIngredients { }

     class PopTart extends Sandwich implements 
NontraditionalIngredients, NonTraditionalStructure { }

(see, e.g., https://twitter.com/matttomic/status/859117370455060481, for 
those who don't get the joke.)

The constraint we would like to express here is that the interfaces 
WithCheese and Toasted exist to serve Sandwich, which is 
extension-controlled.  To capture this, we also seal these interfaces, 
but now have to redundantly enumerate their subtypes.  This is annoying 
and brittle, because we're stating it indirectly; a more direct capture 
of intent would be to say "Toasted can only be used with Sandwich."

Even if Sandwich were an interface, and then we can say "Toasted extends 
Sandwich", we still have to redundantly enumerate the subtypes.  If this 
game is about Sandwich, just having Sandwich enumerate its subtypes 
should be enough.

Without trying to paint the bikeshed, this is a pretty simple extension 
to sealing:

     sealed interface WithCheese __refines Sandwich { }

This says that WithCheese is sealed to either classes that extend 
Sandwich, or other interfaces that __refines Sandwich.  As a bonus, 
default methods in WithCheese can refer to methods in Sandwich, since it 
must always be the case that `this instanceof Sandwich`.

Essentially, I want to put the `permits` list on Sandwich, and have 
`WithCheese` and friends delegate their permits to `Sandwich`, rather 
than having each interface enumerate their subtypes.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20210401/2c786f4a/attachment.htm>


More information about the amber-spec-experts mailing list