Scala构造函数重载?

142

在Scala中如何提供重载构造函数?

5个回答

193

值得明确提到的是,在Scala中,辅助构造函数必须首先调用主构造函数(如landon9720的答案),或者同一类中的另一个辅助构造函数作为它们的第一个操作。它们不能像在Java中那样显式或隐式地调用超类的构造函数。这确保了主构造函数是进入类的唯一入口。

class Foo(x: Int, y: Int, z: String) {  
  // default y parameter to 0  
  def this(x: Int, z: String) = this(x, 0, z)   
  // default x & y parameters to 0
  // calls previous auxiliary constructor which calls the primary constructor  
  def this(z: String) = this(0, z);   
}

@Jon McAuliffe:不好的例子?如果没有第二个和第三个构造函数,用户仍然可以调用new Foo(x=2,z=4)new Foo(z=5),只要你将第一行改为class Foo(x: Int = 0, y: Int = 0, z: String) { - user2987828
命名/默认参数直到Scala 2.8才出现。 - Jon McAuliffe
2
值得一提的是如何使用重载构造函数。即使对于 case 类,使用 new 关键字也是必要的,这并不是微不足道的。 - Readren

33
 class Foo(x: Int, y: Int) {
     def this(x: Int) = this(x, 0) // default y parameter to 0
 }

16

从Scala 2.8.0开始,您还可以为构造函数和方法参数设置默认值。像这样:

scala> class Foo(x:Int, y:Int = 0, z:Int=0) {                           
     | override def toString() = { "Foo(" + x + ", " + y + ", " + z + ")" }
     | }
defined class Foo

scala> new Foo(1, 2, 3)                                                    
res0: Foo = Foo(1, 2, 3)

scala> new Foo(4)                                                          
res1: Foo = Foo(4, 0, 0)

在参数列表中,具有默认值的参数必须放在没有默认值的参数之后。


3
对于非平凡的默认值,这种方法行不通。因此class Foo(val x:Int, y:Int=2*x)不起作用。 - subsub
@Jörgen Lundberg:你写道,带有默认值的参数必须在参数列表中没有默认值的参数之后。这是错误的,“new Foo(x=2,z=4)”将打印“Foo(2,0,4)”。 - user2987828
@user2987828 我的意思是你不能写成 new Foo(12, x=2),而应该写成 new Foo(x=2, 12)。你可以写成 new Foo(12, y=2),这样你会得到 Foo(12, 2, 0)。 - Jörgen Lundberg

10
在查看我的代码时,我突然意识到我有点过载了构造函数。然后我想起了那个问题,回来给出另一个答案:
在Scala中,你不能重载构造函数,但你可以使用函数来实现这个功能。
此外,许多人选择使伴生对象的apply函数成为相应类的工厂。
通过将这个类定义为抽象类并重载apply函数以实现-实例化这个类,你就可以拥有重载的“构造函数”。
abstract class Expectation[T] extends BooleanStatement {
    val expected: Seq[T]
    …
}

object Expectation {
    def apply[T](expd:     T ): Expectation[T] = new Expectation[T] {val expected = List(expd)}
    def apply[T](expd: Seq[T]): Expectation[T] = new Expectation[T] {val expected =      expd }

    def main(args: Array[String]): Unit = {
        val expectTrueness = Expectation(true)
        …
    }
}

注意,我明确定义每个apply返回Expectation[T],否则它将返回一个鸭子类型的Expectation[T]{val expected: List[T]}

0

试试这个

class A(x: Int, y: Int) {
  def this(x: Int) = this(x, x)
  def this() = this(1)
  override def toString() = "x=" + x + " y=" + y
  class B(a: Int, b: Int, c: String) {
    def this(str: String) = this(x, y, str)
    override def toString() =
      "x=" + x + " y=" + y + " a=" + a + " b=" + b + " c=" + c
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接