Paweł Żurkiewicz
Paweł Żurkiewicz

Reputation: 257

Initialize a class instance with trait fields in constructor

I have created abstract class and trait

abstract class Person(val name: String){
 val tax: Double;
}

trait Employee {
 var salary: Double;
 val tax: Double = salary * 0.3;
}

and I want to create an instance of class object

val examplePerson = new Person("John") with Employee;

I get Erorr

Description Resource Path Location Type object creation impossible, since variable salaryin trait Emplyee of type Double is not defined (Note that variables need to be initialized to be defined) Scala Problem

But i don't know how to set field salary with constructor while initializing. Is it possible?

When I tried setting a default value

var salary: Double = 0.0;

and then use a setter on examplePerson instance, tax is not changing becouse is immutable (it must be val).

Upvotes: 0

Views: 262

Answers (1)

jwvh
jwvh

Reputation: 51271

This will compile...

val examplePerson = new Person("John") with Employee {
  override var salary: Double = 40.1
}

...but the tax value won't reflect it because the calculation is done before the override.

examplePerson.tax  //res0: Double = 0.0

One simple fix for that is to make the tax value lazy.

trait Employee {
  var salary: Double
  lazy val tax: Double = salary * 0.3
}

Then the calculation is computed when tax is referenced for the first time.

examplePerson.tax  //res0: Double = 12.03

But be aware that once a val is evaluated (lazily or otherwise) it will never change, so if salary is ever modified, the tax value won't reflect it.

Note: This is Scala, where using var is discouraged and semi-colons, ;, are (mostly) unneeded.

Upvotes: 3

Related Questions