Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala class members and constructor parameters name clash

Tags:

Consider the following class written in Java:

class NonNegativeDouble {
    private final double value;
    public NonNegativeDouble(double value) {
        this.value = Math.abs(value);
    }
    public double getValue() { return value; }
}

It defines a final field called value that is initialized in the constructor, by taking its parameter called alike and applying a function to it.

I want to write something similar to it in Scala. At first, I tried:

class NonNegativeDouble(value: Double) {
  def value = Math.abs(value)
}

But the compiler complains: error: overloaded method value needs result type

Obviously the compiler thinks that the expression value inside the expression Math.abs(value) refers to the method being defined. Therefore, the method being defined is recursive, so I need to state its return type. So, the code I wrote does not do what I expected it to do: I wanted value inside Math.abs(value) to refer to the constructor parameter value, and not to the method being defined. It is as if the compiler implicitly added a this. to Math.abs(this.value).

Adding val or var (or private ... variants) to the constructor parameter doesn't seem to help.

So, my question is: can I define a property with the same name as a constructor parameter, but maybe a different value? If so, how? If not, why?

Thanks!

like image 930
Bruno Reis Avatar asked Sep 22 '10 01:09

Bruno Reis


People also ask

Can constructors take any number of parameters?

We can have any number of Parameterized Constructor in our class. In this example, I have implemented four constructors: one is default constructor and other three are parameterized. During object creation the parameters we pass, determine which constructor should get invoked for object initialization.

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.

Can constructors receive parameters?

Constructors can also take parameters, which is used to initialize attributes.

Can objects have constructors Scala?

Constructors in Scala describe special methods used to initialize objects. When an object of that class needs to be created, it calls the constructor of the class. It can be used to set initial or default values for object attributes.


2 Answers

No, you can't. In Scala, constructor parameters are properties, so it makes no sense to redefine them.

The solution, naturally, is to use another name:

class NonNegativeDouble(initValue: Double) {
  val value = Math.abs(initValue)
}

Used like this, initValue won't be part of the instances created. However, if you use it in a def or a pattern matching declaration, then it becomes a part of every instance of the class.

like image 141
Daniel C. Sobral Avatar answered Oct 05 '22 01:10

Daniel C. Sobral


@Daniel C. Sobral

class NonNegativeDouble(initValue: Double) {
  val value = Math.abs(initValue)
}

your code is right, but "constructor parameters are properties",this is not true.

A post from the official site said,

A parameter such as class Foo(x : Int) is turned into a field if it is referenced in one or more methods

And Martin's reply confirms its truth:

That's all true, but it should be treated as an implementation technique. That's why the spec is silent about it.

So normally, we can still treat primary constructor parameters as normal method parameter, but when the parameters is referenced by any of the methods, the compiler will cleverly turn it into a private field.

If any formal parameter preceded by the val, the compiler generates an getter definition automatically.if var, generates a setter additionally. see the language speification section 5.3.

That's all about primary constructor parameters.

like image 45
soulmachine Avatar answered Oct 04 '22 23:10

soulmachine