Reputation: 3459
I found an interesting condition with traits:
scala> trait Thing[A]
defined trait Thing
scala> val myThing: Thing[Int] = new Thing[Int]
error: trait Thing is abstract; cannot be instantiated
scala> val myThing: Thing[Int] = new Thing[Int] { }
myThing: Thing[Int] = $anon$1@135f160e
Why does having the code block allow me to create an instance of the Thing trait?
Upvotes: 2
Views: 401
Reputation: 48420
Another way of looking at it is the keyword new
invokes a constructor, however trait does not have a constructor, so
new Thing[Int]
cannot be instantiated. But where is the constructor in
new Thing[Int] { }
you might ask? Well, the "empty code block" actually defines the constructor. This constructor indeed has no statements in it (besides invoking the super constructor), however now new
at least has something to invoke. Similarly,
class Bar
trait Qux
new Bar // ok because class has a constructor (by default)
new Qux // error because trait has no constructor
The precise term to search for in SLS is general instance creation expression as explained here.
Upvotes: 2
Reputation: 5782
You cannot instantiate the trait directly. When adding the {}
, you're creating an anonymous class which can be instantiated.
Similar question posted elsewhere:
Upvotes: 3
Reputation: 55569
It's a feature of the language called an anonymous class. When you write new Thing[Int] { }
, the compiler creates a new class with the name $anon$1
(or something similar) that extends Thing[Int]
, and then creates a new instance of $anon$1
.
Upvotes: 6