Estoy jugando con las clases selladas de vista previa en Java 15, y me preguntaba por qué las palabras clave sealed
y non-sealed
solo se aplican a las clases e interfaces, pero no a los métodos (como lo hacen otros modificadores). Me imagino que podría ser útil decidir específicamente cuál de los métodos puede ser anulado por las subclases permitidas.
Un ejemplo: tengo una clase Unit
que tiene dos subclases Metric
e Imperial
, que finalmente implementan una funcionalidad básica, aquí kind()
.
public abstract sealed class Unit permits Imperial, Metric { public abstract String kind (); } public abstract non-sealed class Imperial extends Unit { @Override public final String kind() { return "imperial"; } } public abstract non-sealed class Metric extends Unit { @Override public final String kind() { return "metric"; } }
Esto funciona. Sin embargo, ahora no quiero implementar kind()
en todas las subclases, sino proporcionar una implementación que sea definitiva para todas las subclases, excepto aquellas en las que se permite la anulación. En mi mente esto se vería así:
public abstract sealed class Unit permits Imperial, Metric { // this is not supported public sealed String kind () permits Imperial {return "easy"; } } public abstract non-sealed class Imperial extends Unit { @Override public final String kind() { return "oh my god"; } } public abstract non-sealed class Metric extends Unit { // should not be possible to override kind() here or in any subclass }
¿Hay alguna forma de que pueda lograr esto con las nuevas funciones o hay alguna otra forma que me falta?
Puede hacer esto con clases de acceso a paquetes.
Coloque las tres clases en su propio paquete y delegue kind()
a un método privado del paquete, es decir, un método que no sea ni público ni protegido ni privado. Esto permitirá que solo las clases en ese paquete lo anulen:
package com.example.units; public abstract sealed class Unit permits Imperial, Metric { public final String kind () { return kindImpl(); } String kindImpl() { return "easy"; } } package com.example.units; public abstract class Imperial extends Unit { @Override String kindImpl() { return "imperial"; } }
kindImpl()
es un paquete privado, por lo que solo las clases en el mismo paquete pueden anularlo.
Esto funciona en cualquier versión de Java, independientemente de si se están utilizando clases selladas.