Alex Rivera | Logout

Java Constructor Inheritance

Asked 2009-10-29T14:59:18.227
214

I was wondering why in java constructors are not inherited? You know when you have a class like this:

public class Super {

  public Super(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
    this.serviceA = serviceA;
    //etc
  } 

}

Later when you inherit from Super, java will complain that there is no default constructor defined. The solution is obviously something like:

public class Son extends Super{

  public Son(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
    super(serviceA,serviceB,serviceC);
  }

}

This code is repetitive, not DRY and useless (IMHO)... so that brings the question again:

Why java doesn't support constructor inheritance? Is there any benefit in not allowing this inheritance?

Edit
Report

1 Answer

12

Because constructing your subclass object may be done in a different way from how your superclass is constructed. You may not want clients of the subclass to be able to call certain constructors available in the superclass.

A silly example:

class Super {
    protected final Number value;
    public Super(Number value){
        this.value = value;
    }
}

class Sub {
    public Sub(){ super(Integer.valueOf(0)); }
    void doSomeStuff(){
        // We know this.value is an Integer, so it's safe to cast.
        doSomethingWithAnInteger((Integer)this.value);
    }
}

// Client code:
Sub s = new Sub(Long.valueOf(666L)): // Devilish invocation of Super constructor!
s.doSomeStuff(); // throws ClassCastException

Or even simpler:

class Super {
    private final String msg;
    Super(String msg){
        if (msg == null) throw new NullPointerException();
        this.msg = msg;
    }
}
class Sub {
    private final String detail;
    Sub(String msg, String detail){
        super(msg);
        if (detail == null) throw new NullPointerException();
        this.detail = detail;
    }
    void print(){
        // detail is never null, so this method won't fail
        System.out.println(detail.concat(": ").concat(msg));
    }
}
// Client code:
Sub s = new Sub("message"); // Calling Super constructor - detail is never initialized!
s.print(); // throws NullPointerException

From this example, you see that you'd need some way of declaring that "I want to inherit these constructors" or "I want to inherit all constructors except for these", and then you'd also have to specify a default constructor inheritance preference just in case someone adds a new constructor in the superclass... or you could just require that you repeat the constructors from the superclass if you want to "inherit" them, which arguably is the more obvious way of doing it.

answered 2009-10-29T15:18:05.270

Your Answer