在Scala中,我如何使用多个构造函数对Java类进行子类化?

假设我有一个具有多个构造函数的Java类:

class Base {
    Base(int arg1) {...};
    Base(String arg2) {...};
    Base(double arg3) {...};
}

如何在 Scala 中扩展它,同时仍然提供对 Base 所有三个构造函数的访问?在 Scala 中,子类只能调用它的超类构造函数之一。如何绕过此规则?

假设 Java 类是我无法更改的旧代码。


答案 1

人们很容易忘记,一个特质可能会扩展一个类。如果使用 trait,则可以推迟决定调用哪个构造函数,如下所示:

trait Extended extends Base {
  ...
}

object Extended {
  def apply(arg1: Int) = new Base(arg1) with Extended
  def apply(arg2: String) = new Base(arg2) with Extended
  def apply(arg3: Double) = new Base(arg3) with Extended
}

特征本身可能没有构造函数参数,但您可以使用抽象成员来解决此问题。


答案 2

编辑 - 这是来自scala邮件列表上的一个问题,我认为在这里重复了。我的答案涉及提供三个不同的构造函数(即复制Java设计),而不是扩展类

假设每个构造函数最终都创建了对象的状态,请使用“静态”方法创建一个伴随对象来创建此状态S

object Base {
  private def stateFrom(d : Double) : S = error("TODO")
  private def stateFrom(s : Str) : S = error("TODO")
  private def stateFrom(i : Int) : S = error("TODO")
} 

然后创建一个私有构造函数,该构造函数采用状态和(公共)重载构造函数,这些构造函数遵从主构造函数

import Base._
class Base private(s : S) { //private constructor takes the state
  def this(d : Double) = this(stateFrom(d)) 
  def this(str : String) = this(stateFrom(str))
  def this(i : Int) = this(stateFrom(i))
  //etc
}