密封类和密封接口sealed和permits关键字

1.sealed和permits

类和接口上可以添加sealed关键字,用来限定自己可以派生出哪些子类.换句话说,就是控制哪些子类可以继承或者实现自己,不允许其他类派生.

sealed class Base permits D1,D2{}
final class D1 extends Base{}
final class D2 extends Base{}

如上述代码所示,Base只允许D1和D2继承自己,其他类继承会报编译错误.

public sealed interface Ifc {

}

final class Imp1 implements Ifc{}
final class Imp2 implements Ifc{}

子类可以写在不同的文件中.如果子类和父类在同一个文件中,则不需要写permits语句.如上述代码所示,没有写permits关键字,也能正常编译.

2.non-sealed

sealed的子类只能通过final,sealed,non-sealed关键字来定义,如果不加final或者其他关键字,会编译报错.

non-sealed关键字表示允许未知的子类继承被修饰的类.

public sealed class Super permits Sub1, Sub2{

}
final class Sub1 extends Super{}
non-sealed class Sub2 extends Super{}
class Any1 extends Sub2{}
class Any2 extends Sub2{}

如上述代码所示,Sub2在没有permits关键字的情况下也可以被Any1和Any2继承;

3.record

record关键字是隐式的final,所以record也可以不加final继承密封类.

record类似于lombok的@Data注解,可以自己实现equals,toString,hashcode方法等.

用了record关键后,也可以继承密封类.

public sealed interface Employee permits CLevel, Programmer{

}
record CLevel(String type) implements Employee{}
record Programmer(String experience) implements Employee{}

4.getPermittedSubclasses方法

通过反射的getPermittedSubclasses方法我们可以直接获取被允许继承的子类,也就是permits关键字允许的类.

public sealed class Color permits Red,Green,Blue{

}
final class Red extends Color{}
final class Green extends Color{}
final class Blue extends Color{}
public class PermittedSubCLasses {
    public static void main(String[] args) {
        for(var p: Color.class.getPermittedSubclasses()) {
            System.out.println(p.getSimpleName());
        }
    }
}

通过Class<T>类的getPermittedSubclasses方法可以直接获取子类的名称以及其他属性.


 

posted @ 2023-01-30 23:11  随意的马蒂洛克  阅读(464)  评论(0编辑  收藏  举报