Search code examples
scalainheritanceconstructorpolymorphismsuperclass

Using alternative super class constructor in child class instantiation


I have a base class with two constructors, and a child class which has one constructor. Is it possible to instantiate a child class using the second base class constructor?

Example code:

abstract class RuleCondition(rule:Rule, field:String, equal:Boolean, inverted:Boolean)
{
  // alternate constructor with RuleValue instead of static comparation value

  def this(rule:Rule, field:String, ref:RuleValue, equal:Boolean = false, inverted:Boolean = false) = ???
 }

class RuleConditionAbove(rule:Rule, field:String, comparationValue:Long, equal:Boolean = false, inverted:Boolean = false)
  extends RuleCondition(rule, field, equal, inverted)
{
    // ...
}

Now I can do this:

val myAboveCondition = new RuleConditionAbove(rule, "bla", 10, true, false)

but I cannot do this:

val myAboveCondition = new RuleConditionAbove(rule, "bla", RuleValue(...), true, false)

because the alternative constructor of RuleCondition base class is not visible. It will be visible once I add this to the child class:

def this(rule:Rule, field:String, ref:RuleValue, equal:Boolean = false, inverted:Boolean = false) = this(rule, field, ref, equal, inverted)

Would this be the only/usual way of solving this issue, or is there something smarter which involves less copy & past code? (since I have a ton of child classes of the same pattern)

[edit] To clarify, the second constructor would be the same in every child class, thus I would like to have it implemented only once in the base class. However still having to put another constructor in each child class would defeat this purpose somehow, and thus I would not have two constructors in the base class but rather only in all child classes.


Solution

  • Is it possible to instanciate a child class using the [second] base class constructor?

    No.

    You can never use a superclass constructor to create an instance of a subclass. You have to call a constructor for the class that you are creating. The subclass constructor must call a constructor for the superclass, but you can't call it directly.

    So the reason that you can do this

    val myAboveCondition = new RuleConditionAbove(rule, "bla", 10, true, false)
    

    is that RuleConditionAbove has a constructor with those arguments. It has nothing to do with the fact that RuleCondition has a constructor with the same arguments.

    And the reason that you can't do this

    val myAboveCondition = new RuleConditionAbove(rule, "bla", RuleValue(...), true, false)
    

    is that RuleConditionAbove does not have a constructor with those arguments.