代码之家  ›  专栏  ›  技术社区  ›  Seth Tisue Arthur Hjorth

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

  •  55
  • Seth Tisue Arthur Hjorth  · 技术社区  · 14 年前

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

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

    如何在Scala中扩展它,并且仍然提供对Base的所有三个构造函数的访问?在Scala中,子类只能调用其超类的一个构造函数。我怎样才能绕过这个规则呢?

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

    4 回复  |  直到 14 年前
        1
  •  92
  •   Seth Tisue Arthur Hjorth    14 年前

    很容易忘记一个特质可以扩展一个类。如果使用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
    }
    

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

        2
  •  5
  •   oxbow_lakes    14 年前

    编辑 这是来自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
    }
    
        3
  •  2
  •   corsiKa    14 年前

    我会选择最通用的一个(在本例中是字符串),如果它满足其他条件,我会自己进行内部转换。

    虽然我承认这不是最好的解决办法,但我觉得这有点不对劲-(

        4
  •  2
  •   JAB    14 年前

    在Java中编写一个子类,实现一个构造函数,该构造函数接受其他各种构造函数将接受的所有输入,并根据输入的存在或不存在(通过使用“null”或某种sentinel值)调用其超类的适当构造函数,然后在Scala中对Java类进行子类化,并将sentinel值指定为默认参数。