Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why scala class need to explicitly extend AnyRef

Tags:

scala

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
like image 615
jiangok Avatar asked Jul 21 '15 17:07

jiangok


2 Answers

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
like image 55
Gabriele Petronella Avatar answered Nov 15 '22 22:11

Gabriele Petronella


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.

like image 23
Monads are like... Avatar answered Nov 15 '22 22:11

Monads are like...