我看到了库中的一些代码:
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
答案 0 :(得分:8)
答案 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的子类,称为用户定义的值类,由编译器专门处理。正确定义的用户值类提供了一种方法,通过避免在运行时分配对象,以及通过静态方法调用替换虚方法调用来提高用户定义类型的性能。