Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - how to call different super() according to inheriting class's constructor argument?

I am trying to make the inheriting class ask for less arguments, and calculate the 'correct' mising arguments for the super class. Looking for help on how to do this, without using factory methods.

This is an example code to simplify things. Son(int) will call super(int,boolean) based on the value of int.

class Base {
  ...
  public Base (int num, boolean boo2) { ...}
  ...
}

class Son extends Base {
  ...
  public Son (int num) {
    if (num > 17)
       super(num, true);
    else
      super(num , false);
  }
  ...
}

I also considered making Base an interface, but that doesn't allow me to enforce some argument correctness checks.

Appreciate your help.

like image 847
Oron Avatar asked Jan 08 '14 15:01

Oron


3 Answers

I'm not 100% sure, but could this work?

class Son extends Base {
  ...
  public Son (int num) {
       super(num, (num>17));
  }
  ...
}
like image 118
Oscar Pérez Avatar answered Sep 22 '22 04:09

Oscar Pérez


If finding the other arguments is a complex operation (i.e., cannot be reduced to a single expression) you can add a static method that do that for you and refer to it in the super call, something like:

Class Son extends Base {

  private static boolean getMyBoolean(int num) {
    return num > 17; //or any complex algorithm you need.
  }

  public Son (int num) {
    super(num, getMyBoolean(num));
  }
  ...
}

Otherwise, if the missing arguments can be calculated using a simple expression (as in the concrete example you give), just write:

Class Son extends Base {
  public Son (int num) {
    super(num, num > 17);
  }
  ...
}
like image 31
Sergio Avatar answered Sep 24 '22 04:09

Sergio


The super() call must be the first statement in the constructor. In this case you can use:

class Base {
    public Son(int num) {
        super(num, num > 17);
    }
}

If the calculation work that you need to do is longer than a single expression, you can move it into a static method that you call from the constructor:

class Son extends Base {
    public Son(int num) {
        super(num, calcBoo(num));
    }

    private static boolean calcBoo(int num) {
        if (num > 17)
            return true;
        else
            return false;
    }
}

Another option is to hide the constructor and add a static factory method, which would let you do arbitrarily complex work before calling the super constructor:

class Son extends Base {
    private Son(int num, boolean boo) {
        super(num, boo);
    }

    public static Son create(int num) {
        boolean boo;
        // ... statements here ... //
        return new Son(num, boo);
    }
}
like image 33
Boann Avatar answered Sep 25 '22 04:09

Boann