【问题标题】:Scala constructor signatureScala构造函数签名
【发布时间】:2014-03-13 13:06:47
【问题描述】:

是否可以在 Scala 中定义构造函数签名?

abstract class A {
    def this (s: String): this.type // doesn't work
    def this (i: Int): this.type    // doesn't work
    def this (d: Double): this.type // doesn't work
}

class B(var s: String) extends A {
    def this(i: Int) = {
        this("int "+i.toString())
    }
    def this(d: Double) = {
        this("double "+d.toString())
    }
}

【问题讨论】:

    标签: scala constructor abstract-class abstract


    【解决方案1】:

    你想达到什么目的?你可以这样做:

    abstract class A(i: Int)
    
    case class B(s: String) extends A(s.toInt) {
      def this(i: Int) = {
        this(i.toString)
      }
    
      def this(d: Double) = {
        this(d.toString)
      }
    }
    

    用法:

    B("1")
    new B(1)
    new B(1.0)
    

    【讨论】:

    • 抽象类作为接口使用。
    • 如果你试图保证你的类有一个单参数 Int 构造函数——这是不可能的
    • 说“抽象类被用作接口”是无稽之谈。 Scala 中的特征和 Java 中的接口与抽象类(在任何一种语言中)有非常不同的使用限制。
    • 好的,但问题与这里的特征而不是抽象类相同,对吧?如果需要,我可以写一个更详细的示例来说明我正在努力实现的目标。
    • 特征可能根本没有构造函数参数。不要与它们没有构造函数混淆,因为它们有,只是那些构造函数不能带参数。
    【解决方案2】:

    正如其他答案所指出的那样,您不能完全按照自己的意愿行事,但一种方法是使用工厂:

    trait Foo { 
      // methods you need
    }
    
    trait FooCompanion[T <: Foo] {
      // these methods replace constructors in your example
      def apply(s: String): T
      def apply(i: Int): T
      ...
    }
    

    实施:

    class Bar(s: String) extends Foo {
      ...
    }
    
    object Bar extends FooCompanion[Bar] {
      def apply(s: String) = new Bar(s)
      ...
    }
    

    您可以使用FooCompanion 的方法。这种模式用于例如在 Scala 集合库中。

    【讨论】:

      【解决方案3】:

      不,那是不可能的。构造函数很特殊:你需要写new X()而不是X(),并且没有多态调度,例如你不能做def test[A]() = new A()。因此,在任何情况下抽象构造函数都没有任何意义。

      【讨论】:

        猜你喜欢
        • 2018-08-25
        • 1970-01-01
        • 2013-09-08
        • 2011-02-11
        • 2013-06-14
        • 2012-01-09
        • 2011-04-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多