What is the difference between declaring a field as val
, lazy val
and object
inside a scala class, as in the following snippet:
class A class B { val a1 = new A { def foo = 1 } object a2 extends A { def foo = 1 } lazy val a3 = new A { def foo = 1 } }
In Scala, an object of a class is created using the new keyword. The syntax of creating object in Scala is: Syntax: var obj = new Dog();
Definition: A class is defined with the class keyword while an object is defined using the object keyword. Also, whereas a class can take parameters, an object can't take any parameter. Instantiation: To instantiate a regular class, we use the new keyword.
This class defines two variables x and y and a method: move, which does not return a value. Class variables are called, fields of the class and methods are called class methods. The class name works as a class constructor which can take a number of parameters.
In Scala, an object is a named instance with members such as fields and methods. An object and a class that have the same name and which are defined in the same source file are known as companions.
In the former, any code included is executed as soon as class B is created. In the latter, however, until you actually use the object, it won't be instantiated.
You can see the difference here:
class A { println("Creating a new A") } class B { val a1 = new A { println("a1"); def foo = 1 } object a2 extends A { println("a2"); def foo = 1 } } scala> val b = new B Creating a new A a1 b: B = B@1176e8a scala> b.a2.foo Creating a new A a2 res0: Int = 1
There are also hidden differences in what the created .class files are named and such; and of course the two have different types.
I'm not sure that aioobe recognized the significance of his answer, but the different types actually represent a critical difference between vals
and objects
. In particular, the val
and lazy val
have a structural type (e.g. A{def foo: Int}
), while the object
has a singleton type. As a result, calls to the foo
method on the val
s involve reflection, while calls to the foo
method on the object
do not:
class A class B { val a1 = new A { def foo = printStack } object a2 extends A { def foo = printStack } lazy val a3 = new A { def foo = printStack } def printStack() = new Exception().getStackTrace take 3 foreach println } scala> val b = new B b: B = B@5c750 scala> b.a1.foo // the val line124$object$$iw$$iw$B.printStack(<console>:12) line124$object$$iw$$iw$B$$anon$1.foo(<console>:7) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) scala> b.a2.foo // the object line124$object$$iw$$iw$B.printStack(<console>:12) line124$object$$iw$$iw$B$a2$.foo(<console>:8) line128$object$$iw$$iw$.<init>(<console>:9) scala> b.a3.foo // the lazy val line124$object$$iw$$iw$B.printStack(<console>:12) line124$object$$iw$$iw$B$$anon$2.foo(<console>:9) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
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