在Scala中,如何使用多个构造函数inheritance一个Java类?
假设我有一个带有多个构造函数的Java类:
class Base { Base(int arg1) {...}; Base(String arg2) {...}; Base(double arg3) {...}; }
我怎样才能扩展它在斯卡拉,仍然提供访问所有三个基地的构造? 在Scala中,子类只能调用其超类的构造函数之一。 我该如何解决这个规则?
假设Java类是我无法更改的遗留代码。
很容易忘记一个特质可能会扩展一个类。 如果你使用特质,你可以推迟决定调用哪个构造函数,如下所示:
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 }
特征本身可能不具有构造函数参数,但是可以通过使用抽象成员来解决这个问题。
编辑 – 这是从斯卡拉邮件列表上的问题,我认为这里重复。 我的答案涉及到提供三种不同的构造函数(即复制Javadevise),而不是扩展类
假设你的每个构造函数最终创build了对象的状态 S
,用“静态”方法创build一个伴随对象来创build这个状态
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") }
然后创build一个私有的构造函数,将状态和(公共)重载的构造函数推迟到主构造函数
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 }
这是一个愚蠢的答案,可能会有点工作,但如果Java类有太多的构造函数,可能会是太多的努力,但是:
在Java中编写一个子类,实现一个构造函数,该构造函数接受各种其他构造函数所需的所有input,并根据input的存在与否(通过使用“null”或某种标记值)调用其超类的正确构造函数,然后在Scala中对Java类进行子类化,并将标记值分配为默认参数。
我会select最通用的(在这种情况下,string),并自己做内部转换,如果它符合其他标准。
虽然我承认这不是最好的解决办法,但我觉得这是错误的。 🙁