为什么scala类需要显式扩展AnyRef

时间:2015-07-21 17:16:24

标签: scala

我看到了库中的一些代码:

trait A extends scala.AnyRef
trait B extends scala.AnyRef with A

为什么A需要明确扩展AnyRef? Aren所有类隐式派生自AnyRef吗?

为什么B需要扩展AnyRef,即使A已经这样做了?将上述代码更改为:

的区别是什么
trait A
trait B extends A

2 个答案:

答案 0 :(得分:8)

我说没有任何区别。

来自scala documentation

  

用户定义的类默认定义引用类型;即他们总是(间接)子类is NULL

进一步证明这一点

scala.AnyRef

答案 1 :(得分:2)

您不必显式扩展AnyRef。 AnyRef相当于Scala中Java的Object。 通过创建一个类的实例,该实例将隐式扩展AnyRef,无论它是否在其超类中明确提到它。

以下代码只创建一个匿名类,因此它也隐式扩展了AnyRef:

trait A
val a = new A { }

以下是scala-lang.org的解释:

  

所有类的超类scala.Any有两个直接子类scala.AnyVal和scala.AnyRef代表两个不同的类世界:值类和引用类。所有值类都是预定义的;它们对应于类Java语言的原始类型。所有其他类定义引用类型。用户定义的类默认定义引用类型;即他们总是(间接)子类scala.AnyRef。 Scala中的每个用户定义的类都隐式扩展了特征scala.ScalaObject。运行Scala的基础结构中的类(例如Java运行时环境)不会扩展scala.ScalaObject。如果在Java运行时环境的上下文中使用Scala,则scala.AnyRef对应于java.lang.Object。请注意,上图还显示了值类之间称为视图的隐式转换。下面的示例演示了数字,字符,布尔值和函数都是对象,就像其他对象一样:

http://docs.scala-lang.org/tutorials/tour/unified-types.html

自Scala 2.10起,您还可以扩展AnyVal。来自scala-lang.org:

  

AnyVal是所有值类型的根类,它描述未在底层主机系统中实现为对象的值。   在Scala 2.10之前,AnyVal是一个密封的特性。但是,从Scala 2.10开始,可以定义AnyVal的子类,称为用户定义的值类,由编译器专门处理。正确定义的用户值类提供了一种方法,通过避免在运行时分配对象,以及通过静态方法调用替换虚方法调用来提高用户定义类型的性能。