// Declarations of RedFruit/BlueFruit corrected below from `extends
Node` to `extends Fruit`
I don't know what I don't know about "aux classes". I do know that if
you don't nest the concrete leaves, they can't be public in the same
compilation unit:
--Fruit.java--
public sealed interface Fruit { // permits RedFruit, BlueFruit
/* public */ sealed interface RedFruit extends Fruit {}
// permits *berry
/* public */ sealed interface BlueFruit extends Fruit {}
// permits Blueberry
/* public sealed */ class FruitCake implements Fruit {}
// permits nothing; implicitly final
}
/* package-access */ class Strawberry implements Fruit.RedFruit {}
/* package-access */ class Raspberry implements Fruit.RedFruit {}
/* package-access */ class Blueberry implements Fruit.BlueFruit {}
--------------
Putting the concrete leaves in another compilation unit so they can be
public (assume that's the right accessibility) isn't ceremony reduction.
Am I missing something about how this hierarchy should be declared?
Alex
On 8/20/2019 5:05 PM, Brian Goetz wrote:
I do, because the other way to get a class into the same compilation unit, aux
classes, have some limitations. So we’re encouraging the pattern of nesting.
But … I am not sure we want to push it all the way. Consider a type like:
sealed interface Fruit {
interface RedFruit extends Fruit { }
interface BlueFruit extends Fruit { }
class Strawberry implements RedFruit { }
class Raspberry implements RedFruit { }
class Blueberry implements BlueFruit { }
}
Do we want to force Blueberry to be Fruit.BlueFruit.Blueberry (or at least,
twist the user’s arm into it by offering less ceremony?) I think that would be
lame — and worse than lame if the intermediate interfaces (RedFruit, BlueFruit)
were not public. Then we’d be nesting the public types in the nonpublic ones,
and they’d be inaccessible.
You often show the concrete classes as members of a sealed interface. Interface
members are already implicitly public and static; is this a precedent to build
on for a sealed interface? That is, have the nested concrete classes be
implicitly final, and have the interface's implicit `permits` list care about
only nested concrete classes. Top level concrete classes in the same
compilation unit would be handed like concrete classes in other compilation
units: nothing different than today.
Layering sealing on top of nesting has the attraction that it avoids putting
multiple public concrete classes in a single compilation unit. It's right that
the concrete leaves are public, but javac dislikes compilation units with
multiple public types.
Alex