Java: Extending a Class that has Explicit Constructors

By Xah Lee. Date: . Last updated: .

In the following code, why it doesn't compile, but does when B() is defined?

class B {
  int x;
  //B () {x=300;}
  B (int n) {x=n;}
  int returnMe () {return x;}
}

class C extends B {
}

public class Inh3 {
  public static void main(String[] args) {
  }
}

(answer below.)

↓
↓
↓
↓
↓
↓
↓
↓
↓

↓
↓
↓
↓
↓
↓
↓
↓
↓

↓
↓
↓
↓
↓
↓
↓
↓
↓

↓
↓
↓
↓
↓
↓
↓
↓
↓

↓
↓
↓
↓
↓
↓
↓
↓
↓

↓
↓
↓
↓
↓
↓
↓
↓
↓

Solution

the answer to the constructor mystery is that, if one provides any constructor, one must define all constructors.

Peter Molettiere on Apple's Java forum gave excellent answers:

Because there is no default constructor available in B, as the compiler error message indicates. Once you define a constructor in a class, the default constructor is not included. If you define *any* constructor, then you must define *all* constructors.

When you try to instantiate C, it has to call super() in order to initialize its super class. You don't have a super(), you only have a super(int n), so C can not be defined with the default constructor C() { super(); }. Either define a no-arg constructor in B, or call super(n) as the first statement in your constructors in C.

So, the following would work:

class B {
    int x;
    B() { } // a constructor
    B( int n ) { x = n; } // a constructor
    int returnMe() { return x; }
}

class C extends B {
}

or this:

class B {
    int x;
    B( int n ) { x = n; } // a constructor
    int returnMe() { return x; }
}

class C extends B {
    C () { super(0); } // a constructor
    C (int n) { super(n); } // a constructor
}

If you want to make sure that x is set in the constructor, then the second solution is preferable.


Also, see java lang spec https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.8.9. Quote:

8.8.9. Default Constructor

If a class contains no constructor declarations, then a default constructor is implicitly declared. The form of the default constructor for a top level class, member class, or local class is as follows:

The form of the default constructor for an anonymous class is specified in §15.9.5.1.

It is a compile-time error if a default constructor is implicitly declared but the superclass does not have an accessible constructor that takes no arguments and has no throws clause.