I saw some code from a library:
trait A extends scala.AnyRef
trait B extends scala.AnyRef with A
Why does A
need to explicitly extend AnyRef
? Aren't all classes implicitly derived from AnyRef
already?
Why does B
need to extend AnyRef
even though A
already did this? What's the difference to change above code to:
trait A
trait B extends A
I'd say no difference whatsoever.
From the scala documentation
User-defined classes define reference types by default; i.e. they always (indirectly) subclass
scala.AnyRef
.
To further prove the point
scala> trait A
defined trait A
scala> trait B extends A
defined trait B
scala> val a = new A { }
a: A = $anon$1@2d6d8735
scala> val b = new B { }
b: B = $anon$1@47f37ef1
scala> a.isInstanceOf[AnyRef]
res4: Boolean = true
scala> b.isInstanceOf[AnyRef]
res7: Boolean = true
You do not have to explicitly extend AnyRef. AnyRef is the equivalent of Java's Object in Scala. By creating an instance of a class, that instance will be extending AnyRef implicitly regardless of if it was explicitly mentioned in one of its super classes or not.
The following code just creates an anonymous class, thus it also extends AnyRef implicitly:
trait A
val a = new A { }
Here is the explanation from scala-lang.org:
The superclass of all classes scala.Any has two direct subclasses scala.AnyVal and scala.AnyRef representing two different class worlds: value classes and reference classes. All value classes are predefined; they correspond to the primitive types of Java-like languages. All other classes define reference types. User-defined classes define reference types by default; i.e. they always (indirectly) subclass scala.AnyRef. Every user-defined class in Scala implicitly extends the trait scala.ScalaObject. Classes from the infrastructure on which Scala is running (e.g. the Java runtime environment) do not extend scala.ScalaObject. If Scala is used in the context of a Java runtime environment, then scala.AnyRef corresponds to java.lang.Object. Please note that the diagram above also shows implicit conversions called views between the value classs. Here is an example that demonstrates that both numbers, characters, boolean values, and functions are objects just like every other object:
http://docs.scala-lang.org/tutorials/tour/unified-types.html
Since Scala 2.10 you can also extend AnyVal. From scala-lang.org:
AnyVal is the root class of all value types, which describe values not implemented as objects in the underlying host system. Prior to Scala 2.10, AnyVal was a sealed trait. Beginning with Scala 2.10, however, it is possible to define a subclass of AnyVal called a user-defined value class which is treated specially by the compiler. Properly-defined user value classes provide a way to improve performance on user-defined types by avoiding object allocation at runtime, and by replacing virtual method invocations with static method invocations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With