【问题标题】:Scala constructor overload?Scala构造函数重载?
【发布时间】:2009-07-07 23:15:11
【问题描述】:

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

【问题讨论】:

    标签: scala


    【解决方案1】:

    值得一提的是,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:不好的例子?如果没有第二个和第三个构造函数,如果您将第一行更改为class Foo(x: Int = 0, y: Int = 0, z: String) {,用户仍然可以调用new Foo(x=2,z=4)new Foo(z=5)
    • 命名/默认参数直到 Scala 2.8 才出现。
    • 值得一提的是如何使用重载构造函数。即使对于案例类,new 关键字也是必需的,这一点并非微不足道。
    【解决方案2】:
     class Foo(x: Int, y: Int) {
         def this(x: Int) = this(x, 0) // default y parameter to 0
     }
    

    【讨论】:

      【解决方案3】:

      从 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)
      

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

      【讨论】:

      • 这不适用于非平凡的默认值。所以class Foo(val x:Int, y:Int=2*x) 不起作用。
      • @Jörgen Lundberg:你写的带默认值的参数必须在参数列表中没有默认值的参数之后。错了,new Foo(x=2,z=4)会打印Foo(2,0,4)
      • @user2987828 我的意思是你不能写 new Foo(12, x=2) 你必须写 new Foo(x=2, 12)。你可以写 new Foo(12, y=2),然后你会得到 Foo(12, 2, 0)
      【解决方案4】:

      在查看我的代码时,我突然意识到我做了一种构造函数的重载。然后我想起了那个问题,又回来给了另一个答案:

      在 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]}

      【讨论】:

        【解决方案5】:

        试试这个

        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
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2011-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-24
          • 2011-07-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多