Can not instantiate trait with no methods without empty code block

Viewed 237

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?

3 Answers

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.

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.

Related