Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Suppose I have a Java class with multiple constructors:

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

How can I extend it in Scala and still provide access to all three of Base's constructors? In Scala, a subclass can only call one of it's superclass's constructors. How can I work around this rule?

Assume the Java class is legacy code that I can't change.

like image 956
Seth Tisue Avatar asked Jul 21 '10 13:07

Seth Tisue


People also ask

Can a subclass have more than one constructor?

Java Constructor Access Modifiers For instance, if a constructor is declared protected then only classes in the same package, or subclasses of that class can call that constructor. A class can have multiple constructors, and each constructor can have its own access modifier.

Can class have multiple constructors Java?

There can be multiple constructors in a class. However, the parameter list of the constructors should not be same. This is known as constructor overloading.

Can we use multiple constructors in same class?

A class can have multiple constructors that assign the fields in different ways. Sometimes it's beneficial to specify every aspect of an object's data by assigning parameters to the fields, but other times it might be appropriate to define only one or a few.

Can a class have multiple constructors with different names?

No. It is not possible. It might be helpful if you explain what it is you're trying to achieve that makes constructors with different names seem like a desirable solution. What is it you're trying to do with your code?


2 Answers

It's easy to forget that a trait may extend a class. If you use a trait, you can postpone the decision of which constructor to call, like this:

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 themselves have constructor parameters, but you can work around that by using abstract members instead.

like image 137
Seth Tisue Avatar answered Oct 19 '22 05:10

Seth Tisue


EDIT - this is from a question on the scala mailing list which I thought was duplicated here. My answer relates to providing three different constructors (i.e. replicating the Java design), and not extending the class

Assuming that each of your constructors ultimately create the state S of the 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 taking the state and (public) overloaded constructors which defer 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 } 
like image 23
oxbow_lakes Avatar answered Oct 19 '22 06:10

oxbow_lakes