当前位置: 首页 > news >正文

Kotlin密封类

基本语法

要声明一个密封类(sealed class)或密封接口(sealed interface),我们只需要在类或接口前加上 sealed 修饰符:

sealed class CustomError 
sealed interface CustomErrors

解释代码:
密封类和密封接口的区别仅在于类与接口之间的差异,因此我们将继续以密封类为例进行说明。

一个密封类是抽象的,因此它不能被实例化。下面的代码会导致错误:

fun main() {// 密封类型不能实例化val customError = CustomError()
}

解释代码:
但是,当然,你可以扩展它。

就像普通类一样,密封类也可以声明构造函数,但密封类中的构造函数必须是私有的或受保护的:

sealed class CustomError {constructor(type: String) {} // 受保护的(默认)private constructor(type: String, code: Int) {} // 私有的public constructor() {} // 公共构造函数会导致错误
}

解释代码:
你还可以像普通类一样使用主构造函数:

// 主构造函数 
sealed class CustomError(type: String) 

密封类与枚举类的对比

理解密封类的一种很好的方法是将它与枚举类进行对比。基本上,密封类像枚举类,但它更灵活。以下是对比的例子:

enum class Staff(numberOfLessons: Int) {TEACHER(2), MANAGER("Manager is managing")
}

解释代码:
这是枚举类的例子,但枚举类中不能有不同类型的构造参数(例如整数和字符串)。然而,使用密封类时是可以的:

sealed class Staff {class Teacher(val numberOfLessons: Int) : Staff()class Manager(val Responsibility: String) : Staff()object Worker : Staff()
}

解释代码:
枚举常量只有一种类型,而密封类则提供了更多的实例和更大的灵活性。我们可以得出结论:枚举类用于表示一组固定的值,而密封类用于表示给定类的固定子类集合。

枚举类不能继承类或接口,而密封类则可以。例如:

open class Person {fun whoAmI(name: String): String {return "I am $name"}
}sealed class Staff : Person() {class Teacher(val numberOfLessons: Int) : Staff()class Manager(val Responsibility: String) : Staff()object Worker : Staff()
}fun main() {val worker = Staff.Workerprintln(worker.whoAmI("Worker"))
}

解释代码:
我们声明了一个简单的 Person 类,并定义了一个方法,然后扩展了密封类 Staff,这赋予了我们继承的能力。在 main 方法中,我们调用了 Person 类的方法。这样一来,我们就能继承 Person 类中的功能了。

另一方面,如果我们尝试使用枚举类来做相同的事情,会导致错误:

enum class Staff : Person() {//...//
}

密封类与 when 表达式

密封类通常与 when 表达式一起使用,因为每个类都被视为一个案例。以下是一个例子:

sealed class Staff {class Teacher(val numberOfLessons: Int) : Staff()class Manager(val Responsibility: String) : Staff()object Worker : Staff()
}fun listTheTasks(staff: Staff) = when (staff) {is Staff.Teacher -> println("The teacher has ${staff.numberOfLessons} lessons today")is Staff.Manager -> println("The manager is doing ${staff.Responsibility} today")Staff.Worker -> println("Worker is fixing the projector for profs in CS, all respect to him.")
}

解释代码:
我们声明了一个密封类 Staff,其中包含两个类和一个对象。一个对象在没有状态的情况下更为合适。然后我们创建了一个函数 listTheTasks。请注意,在类的情况下,需要使用 is,而在对象的情况下不需要。由于我们处理了所有的案例,因此没有 else 分支。

让我们运行这个函数:

fun main() {val teacher = Staff.Teacher(3)val worker = Staff.WorkerlistTheTasks(teacher)listTheTasks(worker)
}// 输出:
// The teacher has 3 lessons today
// Worker is fixing the projector for profs in CS, all respect to him.

解释代码:
如你所见,when 表达式可以非常方便地处理密封类的每个子类。

直接子类的位置

最后,重要的一点是,密封类和接口的直接子类必须声明在同一个包中。另一方面,这一点对间接子类没有要求。你可能会问,什么是直接子类和间接子类。让我们通过一个简单的例子来澄清:

open class B : A() // B 是 A 的直接子类
open class C : B() // C 是 A 的间接子类,B 的直接子类

解释代码:
如果父类与子类之间没有其他类,那么它就是直接子类。

官方文档中提到:“密封类的所有直接子类在编译时都是已知的。没有其他子类可以出现在模块/包之外。”

结论

在本节中,我们学习了密封类,正如名称所示,“sealed” 限制了类层次结构,在我们需要表示一组固定的子类时非常有用。

我们还发现,密封类像枚举类,但提供了更多的灵活性。我们还学习了如何与 when 表达式一起使用,并讨论了密封类的类层次结构的限制。

http://www.lryc.cn/news/591445.html

相关文章:

  • 6. 工程化实践类:《Webpack 5 性能优化全指南:从构建速度到输出质量》
  • 如何成为高级前端开发者:系统化成长路径。
  • 自动化测试工具 Selenium 入门指南
  • CTF Crypto基础知识
  • python(one day)——春水碧于天,画船听雨眠。
  • Matplotlib 轴标题与刻度字号调整方法
  • SGMD辛几何模态分解 直接替换Excel运行包含频谱图相关系数图 Matlab语言!
  • 多重共线性Multicollinearity
  • pytorch小记(三十一):深入解析 PyTorch 权重初始化:`xavier_normal_` 与 `constant_`
  • cuda编程笔记(8)--线程束warp
  • imx6ull-系统移植篇9——bootz启动 Linux 内核
  • Java全栈工程师面试实录:从电商支付到AI大模型架构的深度技术挑战
  • 软件项目管理学习笔记
  • S7-1200 模拟量模块全解析:从接线到量程计算
  • FreeRTOS学习笔记——常用函数说明
  • MQTT之CONNECT报文和CONNACK报文
  • Qwen3-8B Dify RAG环境搭建
  • @fullcalendar/vue 日历组件
  • SpringCloud面试笔记
  • 【每日刷题】跳跃游戏
  • Apache DolphinScheduler介绍与部署
  • 分布式光伏发电系统中的“四可”指的是什么?
  • 解读PLM系统软件在制造企业研发管理中的应用
  • 18650锂电池点焊机:新能源制造的精密纽带
  • AR智能巡检:制造业零缺陷安装的“数字监工”
  • Git仓库核心概念与工作流程详解:从入门到精通
  • 【java面试day6】redis缓存-数据淘汰策略
  • 二刷 黑马点评 秒杀优化
  • 全面升级!WizTelemetry 可观测平台 2.0 深度解析:打造云原生时代的智能可观测平台
  • Netty-基础知识