¿Es posible tener parámetros de constructor que no se conviertan en campos? Por ejemplo,

class Foo(p1: String, p2: Int) {
    val f1 = p1 * p2
}

El único campo que quiero es f1, no p1 y p2. La idea es derivar campos de parámetros.

0
an0 15 may. 2020 a las 17:11

3 respuestas

La mejor respuesta

Esto es bueno, ya que tanto p1 como p2 no son campos aquí, solo f1. Hacerlos campos es activar o desactivar en lugar de excluir (excepto para las clases de casos, donde todos los parámetros también son campos y no se puede hacer nada al respecto).

Para crear estos campos, deberá agregar var o val, algo así como

class Foo(val p1: String, var p2: Int)

EDITAR: en caso de que desee un campo con el mismo nombre que un parámetro pero de un tipo diferente o algo, puede hacer algo como esto:

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
}

Esto es prácticamente lo mismo que tener un campo llamado p1.

Si también desea establecer campos usando algunas operaciones complejas y usar variables locales, puede usar bloques (y quizás un constructor auxiliar)

class Foo(p1: String, val p2: Int) {
  val _p1: Int = {
    val intermediateVariable: String = p1
    intermediateVariable.toInt
  }
  def p1: Int = _p1

O

class Foo(val p1: Int) {

  def this(p1: String) = this({
    val uselessIntermediateVariable = p1.toInt
    uselessIntermediateVariable
  })
}
3
user 15 may. 2020 a las 14:49

En una clase simple, si no agrega ningún modificador como val o var, los parámetros del constructor son elementos privados. Ejemplo:

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

Se hace la excepción si crea una clase de caso, con el modificador de caso todos los parámetros del constructor serán públicos. Puede hacer que sean privados marcando como privado el parámetro. Ejemplo:

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
2
Alfilercio 15 may. 2020 a las 14:39

Solo para aclarar las respuestas existentes, los parámetros de clase que no son mayúsculas y minúsculas pueden convertirse automáticamente en campos, pero solo si se usan en métodos o inicializadores lazy val, p.

class Foo(p1: String, p2: Int) {
    val f1 = p1 * p2
    def m1() = p1 + p1
}

Hará p1 un campo. No hay forma de evitarlo más que no usarlos de esa manera.

2
Alexey Romanov 15 may. 2020 a las 15:23