What is the difference between defining an object using the new operator vs defining a standalone object by extending the class?
More specifically, given the type class GenericType { ... }
, what is the difference between val a = new GenericType
and object a extends GenericType
?
As a practical matter,
object
declarations are initialized with the same mechanism asnew
in the bytecode. However, there are quite a few differences:object
as singletons -- each belongs to a class of which only one instance exists;object
is lazily initialized -- they'll only be created/initialized when first referred to;object
and aclass
(ortrait
) of the same name are companions;object
generate static forwarders on the companionclass
;object
can access private members of the companionclass
;These are just some of the differences that I can think of right of the bat. There are probably others.
* What are the "relevant" classes or traits is a longer story -- look up questions on Stack Overflow that explain it if you are interested. Look at the wiki for the
scala
tag if you have trouble finding them.While
object
declarations have a different semantic than anew
expression, a localobject
declaration is for all intents and purpose the same thing as alazy val
of the same name. Consider:test1
definesa
as a lazy val initialized with a new instance ofFoo
, whiletest2
definesb
as anobject
extendingFoo
. In essence, both lazily create a new instance ofFoo
and give it a name (a
/b
).You can try it in the REPL and verify that they both behave the same:
So despite the semantic differences between
object
and alazy val
(in particular the special treatment ofobject
's by the language, as outlined by Daniel C. Sobral), alazy val
can always be substituted with a correspondingobject
(not that it's a very good practice), and the same goes for alazy val
/object
that is a member of a class/trait. The main practical difference I can think of will be that the object has a more specific static type:b
is of typeb.type
(which extendsFoo
) whilea
has exactly the typeFoo
.object definition (whether it extends something or not) means singleton object creation.