Java: Extending a Class that has Explicit Constructors
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) { } }
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 default constructor has the same accessibility as the class (§6.6).
- The default constructor has no formal parameters, except in a non-private inner member class, where the default constructor implicitly declares one formal parameter representing the immediately enclosing instance of the class (§8.8.1, §15.9.2, §15.9.3).
- The default constructor has no throws clauses.
- If the class being declared is the primordial class Object, then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.
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.