假设我有一个带有多个构造函数的 Java 类:
class Base {
Base(int arg1) {...};
Base(String arg2) {...};
Base(double arg3) {...};
}
如何在 Scala 中扩展它并仍然提供对 Base 的所有三个构造函数的访问?在 Scala 中,子类只能调用它的超类的构造函数之一。我该如何解决这个规则?
假设 Java 类是我无法更改的遗留代码。
假设我有一个带有多个构造函数的 Java 类:
class Base {
Base(int arg1) {...};
Base(String arg2) {...};
Base(double arg3) {...};
}
如何在 Scala 中扩展它并仍然提供对 Base 的所有三个构造函数的访问?在 Scala 中,子类只能调用它的超类的构造函数之一。我该如何解决这个规则?
假设 Java 类是我无法更改的遗留代码。
很容易忘记一个特征可以扩展一个类。如果使用 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
}
特征本身可能没有构造函数参数,但您可以通过使用抽象成员来解决这个问题。
编辑-这是来自我认为在这里重复的 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
}
我会选择最通用的一个(在本例中为 String),如果它符合其他条件,则自己进行内部转换。
虽然我承认这不是最好的解决方案,而且我觉得它是错误的。:-(
这是一个愚蠢的答案,可能会起作用,但如果 Java 类有太多的构造函数,可能会付出太多的努力,但是:
用 Java 编写一个子类,实现一个构造函数,该构造函数接受所有其他构造函数的输入,并根据输入的存在与否调用其超类的正确构造函数(通过使用“null”或某种标记值),然后在 Scala 中子类化该 Java 类并将标记值分配为默认参数。