Is it possible to have constructor parameters that don't become fields? For example,
class Foo(p1: String, p2: Int) {
val f1 = p1 * p2
}
The only field I want is f1, not p1 and p2. The idea is to derive fields from parameters.
This is good as it is - both p1 and p2 aren't fields here, just f1. Making them fields is opt-in rather than opt-out (except for case classes, where all parameters are also fields, and you can't do anything about it).
To make them fields, you'd have to add var or val, something like
class Foo(val p1: String, var p2: Int)
EDIT: In case you want a field with the same name as a parameter but a different type or something, you can do something like this:
class Foo(p1: String, val p2: Int) {
//Can be val if you want
var _p1: Int = (p1 : String).toInt
def p1: Int = _p1
def p1_=(p1: Int) = _p1 = p1 //An optional setter
}
This is practically the same as having a field called p1.
If you also want to set fields using some complex operations and use local variables, you can use blocks (and maybe an auxiliary constructor)
class Foo(p1: String, val p2: Int) {
val _p1: Int = {
val intermediateVariable: String = p1
intermediateVariable.toInt
}
def p1: Int = _p1
or
class Foo(val p1: Int) {
def this(p1: String) = this({
val uselessIntermediateVariable = p1.toInt
uselessIntermediateVariable
})
}
val. A related question: is it possible to have both a non-field parameter and a filed with the same name?p1_ for?apply.In a simple class, if you don't add any modifier as val or var, the parameters of the constructor are private elements. Example:
class C(val a: Int, b: Int) {
val c = a + b
}
val i = new C(1,2)
println(i.a) // it's public
println(i.b) // this line won't allow you to compile, it's private
println(i.c) // also public
The exception is made is you make a case class, with case modifier all the parameters of the constructor will be public. You can make them private marking as private the parameter. Example:
case class C(a: Int, private val b: Int) {
val c = a + b
}
val i = new C(1,2)
println(i.a) // it's public
println(i.b) // this line won't allow you to compile, it's private
println(i.c) // also public
b isn't private, it isn't stored at all.Just to clarify the existing answers, non-case class parameters can automatically become fields, but only if they are used in methods or lazy val initializers, e.g.
class Foo(p1: String, p2: Int) {
val f1 = p1 * p2
def m1() = p1 + p1
}
will make p1 a field. There's no way to avoid it other than not using them in such a way.