如何在Scala中的构造函数中设置实例成员?

时间:2013-01-29 10:55:38

标签: scala constructor instance member

在Scala中,我需要做一些像Java中的代码一样:

public class A {
  private String text;  
  public A(String text) {
    this.text = text;
  }
}

如何在Scala中实现这一目标?

我知道我可以使用class A(text: String) { ... },但这只是一个非常简单的例子而不是真实案例。

我尝试了以下内容,它始终打印为null:

class A {
  var text: String = null
  def this(text: String) = {
    this()
    this.text = text
  }
  println(text)
}

感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

在Scala类中只有一个主构造函数,它正如你所定义的那样:class A(text: String) { ... }。所有其他构造函数应该首先调用它然后做自己的东西。

类主体中的所有表达式都被视为主构造函数的主体。所以println(text)在你的情况下是在主构造函数的主体中。您首先在this()构造函数中致电def this(text: String),因此println已执行,只有您初始化text字段。


从我的角度来看,主构造函数可以满足大多数实际使用情况(特别是使用默认和命名参数)。那么请您详细说明并解释为什么需要第二个?也许我们可以为您面临的问题找到更好的解决方案。


有关评论的更新

如果您想在施工期间提供一组可选参数,我建议您使用Option代替null值。因此,您可以像这样实施A类:

class A(val a: Option[String] = None, val b: Option[Int] = None, c: Option[Double] = Some(2.0)) 

new A(b = Some(10))

所有字段现在都是常量并且有一些默认值,但您可以自定义其中一些字段。例如,根据某些业务逻辑,某些参数组合也可能是互斥的。在这种情况下,使用几个构造函数是合理的。但是更好的解决方案可以是在类的伴随对象中创建几个工厂方法,并使构造函数成为私有。例如,如果允许该类的用户提供abc,那么您可以编写如下内容:

class A private (val a: Option[String] = None, val b: Option[Int] = None, c: Option[Double] = Some(2.0)) 

object A {
    def apply(a: String, b: Int) = new A(Some(a), Some(b))
    def apply(c: Double) = new A(c = Some(c))
}

A("test", 1)
A(11.1)

答案 1 :(得分:1)

class A {
  var text: String = null
  def this(text: String) = {
    this()
    this.text = text
    println(text)
  }
}

class A(text:String=""){
  println(text)
}

class A(text:String=null){
  println(text)
}

答案 2 :(得分:0)

正确的方法是:

    class A( text : String) {
       def this() = this("") // or null
   }

正如Tenshi所说,默认构造函数是A(text : String),所有其他构造函数,例如this()必须首先调用它。