编程Kotlin开发者,后端开发者,Android开发者

在Kotlin中,密封接口是如何实现的?它们的用途是什么,如何使用,以及与密封类有什么区别?

用 Hintsage AI 助手通过面试

答案。

密封接口是Kotlin中的相对新特性(自1.5版本起),旨在限制接口的实现集合在一个文件内。最初,Kotlin中存在密封类,它们提供了对继承层次的严格控制,使得(例如,在when表达式中)完整处理变得更容易。

问题是,某些架构有时需要的不是基类,而是具有相同实现数量限制的接口。在密封接口出现之前,符合编译器限制的唯一方式是使用密封类,这并不总是与领域模型相匹配,尤其是在需要多重继承或将行为分解成接口时。

解决方案:密封接口允许定义一个接口,其所有实现必须在同一个文件中声明。这提高了代码的安全性,并简化了对状态或事件层次的控制和导航。

示例代码:

密封接口 NetworkState Success(val data: String) : NetworkState Error(val code: Int) : NetworkState 对象 Loading : NetworkState

关键特性:

  • 密封接口只能在同一个文件内实现;
  • 密封接口不存储状态,但它们的实现可以是具有状态的类或对象;
  • 针对密封接口的when表达式支持完整处理。

有陷阱的问题。

可以在声明它的文件之外实现密封接口吗?

不可以。与密封类一样,密封接口只能在声明它们的同一个文件中实现。在文件之外尝试实现这样的接口将导致编译错误。

密封接口可以从类继承吗?

不可以,接口只能从其他接口继承。但密封接口可以从其他(密封)接口继承。

密封接口支持多重实现吗?

是的,同一文件内的类可以实现多个密封接口,或同时继承密封接口和密封类,只要符合语言规则。

常见错误和反模式

  • 在没有声明的文件中实现密封接口(编译器不允许)。
  • 滥用密封接口以增加严格性 — 可能导致架构的复杂性过高。
  • 尝试直接实例化密封接口 — 不可能:只能是具体的实现/对象。

生活中的例子

消极案例

在网络事件处理系统中,开发人员混合使用普通接口和密封类,结果导致“肮脏”的层次结构和代码重复。when表达式不得不包含else分支。

优点:

  • 快速实施的架构
  • 实现的灵活性

缺点:

  • 层次结构的不可控扩展
  • when表达式在覆盖完整性方面没有受到编译器的控制

积极案例

在同一个应用程序中,转向密封接口NetworkEvent,将所有实现放在一个文件中。现在,关于NetworkEvent的when表达式需要处理所有情况。代码变得更易读、可维护且安全。

优点:

  • 完全控制层次结构
  • 在编译阶段支持完整情况处理

缺点:

  • 所有实现必须在一个文件中,当有很多变体时,文件大小会增加