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

Suppose I have a Java class with several constructors:

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

How can I extend it in Scala and provide access to all three base constructors? In Scala, a subclass can call only one of its superclass constructors. How can I get around this rule?

Suppose the Java class is legacy code that I cannot change.

+52
java constructor scala
Jul 21 '10 at 13:35
source share
4 answers

It's easy to forget that a trait can expand a class. If you use a trait, you can defer the decision about which constructor to call, for example:

 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 } 

Traits may not have constructor parameters, but you can get around this by using abstract elements instead.

+85
Jul 21 '10 at 13:40
source share

EDIT is a scala mailing list question which I thought is duplicated here. My answer is related to providing three different constructors (i.e. For replicating a Java design) and not a class extension

Assuming each of your constructors ultimately creates a state S object, create a companion object with static methods to create this state

 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") } 

Then create a private constructor that takes state and (public) overloaded constructors that port to the primary constructor

 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 } 
+5
Jul 21 '10 at 2:00
source share

This is a stupid answer that will probably work somewhat, but might be too large if the Java class has too many constructors, but:

Write a subclass in Java that implements a constructor that accepts all the inputs that other other constructors can use, and names the corresponding constructor of its superclass based on the presence or absence of input data (by using a "null" or some kind of sentinel value), then subclass , which is the Java class in Scala, and assign sentinel values ​​as default parameters.

+2
Jul 21 '10 at 13:59 on
source share

I would choose the most general (in this case String) and do the internal conversion myself if it meets other criteria.

Although I admit that this is not the best solution, and something seems to me wrong. :-(

+1
Jul 21 '10 at 13:36
source share



All Articles