首页 > 编程语言 >Java 密封类 (Sealed Classes) 深度解析

Java 密封类 (Sealed Classes) 深度解析

时间:2024-12-15 23:02:20浏览次数:10  
标签:Java width double height 密封 Classes radius Sealed public

文章目录


Java 作为一种面向对象编程语言,提供了继承机制来实现代码复用和扩展。然而,无限制的继承可能导致代码库变得难以维护,甚至引入安全隐患。为了应对这一挑战,Java引入了密封类的概念。密封类允许开发者明确指定哪些类可以继承该类,从而创建一个封闭且可控的类层次结构。这不仅提高了代码的安全性和可维护性,还为模式匹配等高级特性铺平了道路。

语法说明

定义密封类

密封类是通过 sealed 关键字定义的,并且必须在 permits 子句中列出所有直接子类。这个列表是静态的,意味着一旦编译完成,不能添加新的子类到这个列表中。

public sealed class Shape permits Circle, Rectangle, Square {
    // 类体
}

这段代码定义了一个名为 Shape 的密封类,它只允许 Circle, Rectangle, 和 Square 直接继承它。

定义子类

每个被允许的子类都必须明确声明它们是否可以被进一步继承:

  • 最终类 (final)
    最终类不能再被其他类继承,因此提供了一种绝对的安全性。

    public final class Circle extends Shape {
        private double radius;
    
        public Circle(double radius) {
            this.radius = radius;
        }
    
        public double getRadius() {
            return radius;
        }
    }
    
  • 密封类 (sealed)
    这里的 Rectangle 类仍然是密封的,并且进一步限定了其直接子类。

    public sealed class Rectangle extends Shape permits RoundedRect {
        private double width;
        private double height;
    
        public Rectangle(double width, double height) {
            this.width = width;
            this.height = height;
        }
    
        public double getWidth() {
            return width;
        }
    
        public double getHeight() {
            return height;
        }
    }
    
  • 非密封类 (non-sealed)
    非密封类打破了密封性,意味着它可以被任何类继承。

    public non-sealed class Square extends Shape {
        private double side;
    
        public Square(double side) {
            this.side = side;
        }
    
        public double getSide() {
            return side;
        }
    }
    

使用场景探讨

密封类非常适合用来表示有限但封闭的类型层次结构,比如表达式树、状态机的状态、数据类型的建模等。例如,在一个图形编辑器中,形状的种类是有限的,我们可以使用密封类来确保只有特定类型的形状能够被创建。

此外,密封类也适用于API设计,防止外部代码随意扩展你的API,确保API的行为可控;或者用于框架开发,为框架开发者提供一种限制实现方式的方法,使得框架更加安全和易于维护。

实际应用示例

假设我们正在构建一个图形编辑器,其中形状是有限的,我们可以使用密封类来确保只有特定类型的形状能够被创建。同时,利用密封类与模式匹配结合的优势,简化形状描述逻辑,保证代码的安全性和完整性。

// 定义密封类 Shape
public sealed class Shape permits Circle, Rectangle, Square {}

// 定义最终类 Circle
public final class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }
}

// 定义密封类 Rectangle
public sealed class Rectangle extends Shape permits RoundedRect {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }
}

// 定义非密封类 Square
public non-sealed class Square extends Shape {
    private double side;

    public Square(double side) {
        this.side = side;
    }

    public double getSide() {
        return side;
    }
}

// 定义 RoundedRect 类
public final class RoundedRect extends Rectangle {
    private double cornerRadius;

    public RoundedRect(double width, double height, double cornerRadius) {
        super(width, height);
        this.cornerRadius = cornerRadius;
    }

    public double getCornerRadius() {
        return cornerRadius;
    }
}

// 使用模式匹配来描述形状
public String describeShape(Shape shape) {
    return switch (shape) {
        case Circle c -> "A circle with radius " + c.getRadius();
        case Rectangle r -> "A rectangle with width " + r.getWidth() + " and height " + r.getHeight();
        case Square s -> "A square with side " + s.getSide();
        case RoundedRect rr -> "A rounded rectangle with width " + rr.getWidth() +
                               ", height " + rr.getHeight() +
                               ", and corner radius " + rr.getCornerRadius();
    };
}

在这个例子中,我们展示了如何使用密封类来创建一个封闭的形状层次结构,并通过模式匹配简化对这些形状的处理逻辑。这种方式不仅提高了代码的可读性和安全性,还增强了代码的可维护性。

与其他语言特性的结合使用

密封类与模式匹配的结合是一个强大的组合,特别是从Java 17开始支持的模式匹配特性。通过密封类,编译器可以验证 switch 表达式是否覆盖了所有可能的情况,如果未覆盖,则会给出编译错误。这有助于防止运行时错误,并确保代码的健壮性。

此外,密封类还可以与访问修饰符(如 private, protected, public)、泛型、注解等特性结合使用,以满足不同的设计需求。

标签:Java,width,double,height,密封,Classes,radius,Sealed,public
From: https://blog.csdn.net/2301_77163982/article/details/144494254

相关文章

  • Day32-JavaEE应用&Servlet路由技术&UDBC&Mybatis数据库&生命周期
    一,Servlet&路由&周期1,Servlet的含义:Servlet是运行在web服务器或应用服务器上的程序,它是作为来自web浏览器或其他HTTP客户端请求和HTTP服务器上的数据库或应用程序的中间件。使用Servlet可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页2.Servl......
  • JavaScript是按顺序执行的吗?聊聊JavaScript中的变量提升
    作为一位前端开发者,我们经常会听到这么一句话:“JavaScript的执行是按照顺序自上而下依次执行的。”这句话说的并没有错。但是它似乎又好像不完全对。我们先来看以下这段代码。你觉得结果会输出什么?1showName()2console.log(myName)34varmyName='修谦'5functionshow......
  • 从零开始搭建基于 Maven 和 MyBatis 的 Java 项目
    从零开始搭建基于Maven和MyBatis的Java项目1.修改IDEA中Maven的配置(安转目录本地仓库)2.创建Maven工程3.修改pom.xml文件中的配置信息主要是Maven编译器插件(maven-compiler-plugin)4.导入相关依赖坐标5.创建pojoJavaBean书写实体类6.根据实体类编写SQL语句建......
  • node.js毕设基于Java的心理咨询预约系统 论文+程序
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容一、选题背景关于心理咨询预约系统的研究,现有研究主要以通用的预约系统或医院的预约系统为主[2] 。专门针对高校等特定场景基于Java的心理咨询预约系统的研究较少。......
  • 【Python应用】Jep:将Python无缝嵌入到Java应用程序中,充分发挥两种语言的潜力
    Python以其简洁的语法和丰富的库而闻名,而Java则以其性能和稳定性著称。如果能将两者的优势结合起来,将会产生巨大的开发效率提升。Jep(JavaEmbeddedPython)正是这样一个桥梁,它允许你将CPython无缝嵌入到Java应用程序中,从而充分发挥两种语言的潜力。Jep的核心功能:无缝衔接Java......
  • web前端期末大作业:基于HTML+CSS+JavaScript制作我的音乐网站(带设计报告)
    ......
  • java&springboot&msyql进出校园门禁管理系统79219-计算机毕业设计 原创(附源码)
    摘 要信息化的进出校园门禁管理可以节省人力和物力,并且具有较高的精确性。随着计算机技术和网络技术的迅猛发展,进出校园门禁管理系统不断向着集成化、智能化、网络化与分布式的方向发展。本文主要针对目前大部分高校校园进出管理方式落后、管理效率低下的状况,结合当前最新......
  • 基于java+Springboot+MySQL微信小程序的大用户心理咨询系统设计与实现99040-计算机原
    目录1绪论1.1研究背景1.2研究现状1.3论文结构与章节安排2 基于微信小程序的大用户心理咨询系统设计与实现分析2.1可行性分析2.2系统功能分析2.3 系统用例分析2.4系统流程分析2.5本章小结3基于微信小程序的大用户心理咨询系统设计与实现总体设计......
  • 【学习总结|DAY018】Java异常、泛型、集合框架
    今天学习了Java集合框架,主要内容包括异常、泛型和集合框架。以下是对学习内容的总结,并辅以代码案例加深理解:一、异常异常是程序在编译或执行过程中可能出现的错误,例如数组索引越界、文件不存在等。Java异常体系分为Error和Exception两类,其中Error代表系统级别错误,而Exception......
  • java如何请求接口然后终止某个线程
    Java请求接口并终止线程在Java开发中,处理多线程操作是常见需求。有时我们需要在请求某个接口后,根据接口返回结果或其他条件,终止某个线程的执行。本文将详细介绍如何在Java中请求接口并终止特定线程的方法。一、请求接口1.1使用 HttpURLConnectionJava提供了多种方式进行HTTP......