Java开发入门到精通--Java类(接口)的新类型-密封类
小职 2021-11-16 来源 :码农小胖哥 阅读 393 评论 0

摘要:本篇主要介绍了Java开发入门到精通--Java类(接口)的新类型-密封类,通过具体的内容展现,希望对Java开发的学习有一定的帮助。

本篇主要介绍了Java开发入门到精通--Java类(接口)的新类型-密封类,通过具体的内容展现,希望对Java开发的学习有一定的帮助。

Java开发入门到精通--Java类(接口)的新类型-密封类

密封类是Java 17正式支持的一个新特性,它让Java中类的继承可以更加细粒度的进行控制。今天就来认识一下这个新的功能。

 

密封类

在以往的Java类继承中,Java类的继承控制非常有限,仅能通过final关键字和访问控制符来控制类的继承。例如final类无法被集成;包私有类仅仅只能在该包下进行继承。

 

这显然是不够的。如果一个功能只允许出现在Phone和Pad上,不允许出现在Computer上。如果不对该功能的继承实现进行限制,开发人员将很容易滥用该功能的实现类,错误地重用一些代码。这就是密封类产生的原因。

 

密封类的声明

密封类不仅仅可以是类,也可以是接口。文章中的密封类为统称

 

密封类(接口)可以明确哪些类和接口可以对其扩展或实现。你可以通过sealed修饰符来表明某个类是密封类。但是下面是一个错误的密封类声明:

 

/**

 * 这是一个错误的示范

 */

public sealed interface SealedService {

    

    void doSomething();

}

密封类(接口)在声明的时候必须明确可继承(实现)的范围,所以上面的写法是错误的。必须用permits子句指定允许扩展密封类的类,而且permits关键字位于extends或者implements之后。

 

简而言之,密封类明确了哪些其他类(或接口)可以扩展它们。

 

下面是正确的写法:

 

/**

 * 这是一个正确的示范,明确了可继承的子类为{@link SealedServiceImpl}

 * 该密封类接口同时实现了{@link SuperService}

 */

public sealed interface SealedService extends SuperService permits SealedServiceImpl {

    void doSomething();

}

 

/**

 * 密封类子类

 */

public final class SealedServiceImpl implements SealedService {

    @Override

    public void doSomething() {

        System.out.println("这是一个密封类子类");

    }

}

密封类子类的类型

在上面示例中,密封类(接口)的实现类用了final关键字标记,当然密封类的实现类还可以是密封类:

 

/**

 * 密封类子类

 */

public sealed class SealedServiceImpl implements SealedService permits SonService {

    @Override

    public void doSomething() {

        System.out.println("这是一个密封类子类");

    }

}

 

 

public final class SonService extends SealedServiceImpl {

}

那么难道密封类(接口)的子类只能是final类或者密封类,就不能再扩展了?答案是否定的,只需要使用关键字non-sealed显式声明密封类的继承实现为非密封类就可以继续扩展了。

 

public non-sealed class SealedServiceImpl implements SealedService {

    @Override

    public void doSomething() {

 

    }

 

    /**

     * 用{@code non-sealed}声明非密封类,就可以继续扩展了

     */

    static class NonSealedExtend extends SealedServiceImpl {

 

    }

 

}

总结一下,密封类的子类要么是final Class;要么是sealed Class;要么是non-sealed Class。

 

permits 声明的类必须是直接子类

密封类permits关键字声明的子类必须是直接实现类,为了证明这一点我们这样写:

 

/**

 * 错误的示范

 */

public sealed interface SealedService extends SuperService permits SealedServiceImpl, SonService {

    void doSomething();

}

 

public sealed class SealedServiceImpl implements SealedService permits SonService {

    @Override

    public void doSomething() {

        System.out.println("这是一个密封类子类");

    }

}

 

public final class SonService extends SealedServiceImpl {

}

我使用SonService间接实现了SealedService,结果报错,报错信息要求必须是直接的继承关系。

 Java开发入门到精通--Java类(接口)的新类型-密封类

 

 

错误的密封类继承实现

 

从上图可以看出SonService并非直接实现SealedService,这样会打破密封类的规则,所以无法编译通过。

 

密封类中permits关键字声明的子类必须是直接子类,不可间接实现。

 

密封类不支持匿名类和函数式接口

由于密封类必须明确继承实现关系,所以它不支持匿名类。

 

/**

 * 密封类无法使用匿名类

 *

 * @return the sealed service

 */

public SealedService sealedService(){

    // 提示 Anonymous classes must not extend sealed classes

    return new SealedService() {

        @Override

        public void doSomething() {

             

        }

    };

}

同样也不支持函数式接口:

 

/**

 * 错误的示范

 */

@FunctionalInterface

public sealed interface SealedService permits SealedServiceImpl {

    void doSomething();

}

总结

密封类已经在Java 17中正式转正,这也是Java 17的非常重要的特性之一。对于需要细粒度控制继承关系的场景来说是非常有用的。


✅ 扫码免费获取基础课程·答疑解惑·职业测评

Java开发入门到精通--Java类(接口)的新类型-密封类

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程