John Threepwood
John Threepwood

Reputation: 16143

How to write a class which can be extended with two fields by two traits?

I would like to have a class B which can be extended with two field by two traits A_1 and A_2. It is important, that class B does not have these two fields by itself, since class B should also be able to be used without these to fields.

My first idea:

trait A_1 { val x: Int }
trait A_2 { val y: Int }
class B

But new B with A_1 with A_2 does not work, since x and y are abstract members and need to be defined in class B.

My second idea:

trait A_1 { var x: Int = _}
trait A_2 { var y: Int = _}
class B

Then one could set the fields after creating a object of B:

val b = new B with A_1 with A_2
b.x = 1
b.y = 2

This works, but is a bit ugly, since the values have to be set afterwards. This construction also makes the class mutable.

My third idea:

class A_1 (val x: Int)
class A_2 (val y: Int)

But class B is not allowed to extend multiple classes, so this idea does not work.

Which possibilites are left to realize this situation ? Is there a better way than idea 2. ?

Upvotes: 2

Views: 189

Answers (2)

missingfaktor
missingfaktor

Reputation: 92066

What Nicolas suggested.

Or:

scala> trait A_1 { val x: Int }
trait A_2 { val y: Int }
class B
defined trait A_1
defined trait A_2
defined class B

scala> new { val x = 3; val y = 9 } with B with A_1 with A_2
res3: B with A_1 with A_2 = $anon$1@18e1b

The feature used here is known as early initialization.

Upvotes: 4

Nicolas
Nicolas

Reputation: 24769

You were so close:

scala> trait A1 {val x: Int}
defined trait A1

scala> trait A2 {val y: Int}
defined trait A2

scala> class B
defined class B

scala> new B with A1 with A2 {val x = 4; val y = 2}
res0: B with A1 with A2 = $anon$1@2bc20611

Upvotes: 6

Related Questions