繁体   English   中英

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

[英]In Scala, how can I subclass a Java class with multiple constructors?

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

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

如何在Scala中扩展它并仍然提供对Base的所有三个构造函数的访问? 在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
}

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

编辑 - 这是来自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”或某种类型的sentinel值),然后将Scala中的Java类子类化,并将sentinel值指定为默认参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM