Scala中的final类和sealed类有啥区别?

Posted

技术标签:

【中文标题】Scala中的final类和sealed类有啥区别?【英文标题】:What are the differences between final class and sealed class in Scala?Scala中的final类和sealed类有什么区别? 【发布时间】:2015-11-18 22:05:52 【问题描述】:

Scala 中有两种修饰符:finalsealed

它们之间有什么区别?什么时候应该使用一个而不是另一个?

【问题讨论】:

【参考方案1】:

sealed 类(或特征)仍然可以在同一个源文件中继承(其中final 类根本不能被继承)。

当您想要限制基类的子类数量时使用sealed(请参阅“代数数据类型”)。

作为这种限制的非常实际的好处之一,编译器现在可以警告您非详尽的模式匹配:

sealed trait Duo
case class One(i:Int) extends Duo
case class Two(i:Int, j:Int) extends Duo

def test(d:Duo) 
  match 
    case One(x) => println(x) // warning since you are not matching Two
  

【讨论】:

从技术上讲sealed模板可以在同一个编译单元中扩展,而不是同一个文件。 Scala 编译器的编译单元等于文件这一事实是一个实现细节。可能还有其他编译器使用,例如,数据库来存储源工件而不是文件系统。【参考方案2】:

final 类无法扩展,句号。

sealed trait 只能在其声明的源文件中扩展。这对于创建 ADT(代数数据类型)很有用。 ADT 由其派生类型的 sum 定义。

例如:

Option[A]Some[A] + None 定义。 List[A]:: + Nil 定义。
sealed trait Option[+A]

final case class Some[+A] extends Option[A]
object None extends Option[Nothing]

因为Option[A] 是密封的,它不能被其他开发者扩展 - 这样做会改变它的含义

Some[A] 是最终的,因为它不能被延长,句号。


作为一个额外的好处,如果一个特征是密封的,如果你的模式匹配不够详尽,编译器会警告你,因为它知道Option有限SomeNone

opt match 
    case Some(a) => "hello"

警告:匹配可能并不详尽。它会在以下输入时失败:None

【讨论】:

从技术上讲sealed模板可以在同一个编译单元中扩展,而不是同一个文件。 Scala 编译器的编译单元等于文件这一事实是一个实现细节。可能还有其他编译器使用,例如,数据库来存储源工件而不是文件系统。 @JörgWMittag 感谢您的附录,我不知道这种区别。

以上是关于Scala中的final类和sealed类有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

参数化类和元类有啥区别(请使用 Python 中的代码示例)?

抽象类和静态类有啥区别?

java接口和类有啥区别?

java中接口和类有啥区别 java中接口和类有啥区别

java中接口和类有啥区别java中接口和类有啥区别

java接口与抽象类有啥区别?