Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Scala, how do you define a local parameter in the primary constructor of a class?

In Scala, how does one define a local parameter in the primary constructor of a class that is not a data member and that, for example, serves only to initialize a data member in the base class?

For example, in the following code, how could I properly define parameter b in the primary constructor of class B so that it generates only a temporary local parameter and not a data member?

class A(var a: Int)
class B(?b?) extends A(b)

Randall, your answers explain why the Scala compiler complains when I introduce a method inc that increments the property a, but also change the name of the parameter in the class B constructor to match that of the parameter in the class A constructor:

class A(var a: Int)
class B(a: Int) extends A(a) {
  def inc(value: Int) { this.a += value }
}

Scala compiler output:

$ scala construct.scala
construct.scala:3: error: reassignment to val
  def inc(value: Int) { this.a += value }
                               ^
one error found

Scala complains because class B must now have a private, read-only property a due to the reference to a in inc. Changing B(a: Int) to B(var a: Int) generates a different compiler error:

construct.scala:2: error: error overriding variable a in class A of type Int;
 variable a needs `override' modifier
class B(var a: Int) extends A(a) {
            ^
one error found

Adding override doesn't help, either:

construct.scala:2: error: error overriding variable a in class A of type Int;
 variable a cannot override a mutable variable
class B(override var a: Int) extends A(a) {
                 ^
one error found

How can I use the same name in the parameter in the primary constructor of B as the property defined in the primary constructor of the base class A?

like image 329
Derek Mahar Avatar asked Dec 11 '09 17:12

Derek Mahar


People also ask

What is primary constructor in Scala?

The primary constructor can have zero or more parameters. The parameters of parameter-list are declared using var within the constructor then the value could change. Scala also generates getter and setter methods for that field.

What is constructor parameter in Scala?

If the parameters in the constructor parameter-list are declared using var, then the value of the fields may change. And Scala also generates getter and setter methods for that field. If the parameters in the constructor parameter-list are declared using val, then the value of the fields cannot change.

What is primary and auxiliary constructor in Scala?

A scala class can contain zero or more auxiliary constructor. The auxiliary constructor in Scala is used for constructor overloading and defined as a method using this name. The auxiliary constructor must call either previously defined auxiliary constructor or primary constructor in the first line of its body.

How do you define a class in Scala?

Defining a classA minimal class definition is simply the keyword class and an identifier. Class names should be capitalized. The keyword new is used to create an instance of the class. We call the class like a function, as User() , to create an instance of the class.


Video Answer


1 Answers

If you remove the "var" or "val" keyword from the constructor parameter, it does not produce a property.

Be aware, though, that non-var, non-val constructor parameters are in-scope and accessible throughout the class. If you use one in non-constructor code (i.e., in the body of a method), there will be an invisible private field in the generated class that holds that constructor parameter, just as if you made it a "private var" or "private val" constructor parameter.

Addendum (better late than never??):

In this code the references to the constructor parameter occur only in the constructor body:

class C1(i: Int) {
  val iSquared = i * i
  val iCubed = iSquared * i
  val iEven = i - i % 2
}

... Here the value i exists only during the execution of the constructor.

However, in the following code, because the constructor parameter is referenced in a method body—which is not part of the constructor body—the constructor parameter must be copied to a (private) field of the generated class (increasing its memory requirement by the 4 bytes required to hold an Int):

class C2(i: Int) {
  val iSquared = i * i
  val iCubed = iSquared * i
  val iEven = i - i % 2

  def mod(d: Int) = i % d
}
like image 84
Randall Schulz Avatar answered Sep 30 '22 10:09

Randall Schulz