Rob
Rob

Reputation: 3459

Can not instantiate trait with no methods without empty code block

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

Answers (3)

Mario Galic
Mario Galic

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

Dan W
Dan W

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

Michael Zajac
Michael Zajac

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

Related Questions