Search code examples
javaobjectinheritanceconstructordefault-constructor

Why does compiler complain that superclass has no constructor, when the default constructor is 'automatically' given to a class with no constructor?


All classes have at least one constructor. If a class does not explicitly declare any, the Java compiler automatically provides a no-argument constructor, called the default constructor. This default constructor calls the class parent's no-argument constructor, or the Object constructor if the class has no other parent. If the parent has no constructor (Object does have one), the compiler will reject the program.

(source)

But then, Object is a (direct or indirect) superclass of every class in Java.

Suppose, we have a class A, which does not extend any class explicitly, so it implicitly extends Object. Also suppose, A does not explicitly provide a constructor, so the compiler adds to it a default constructor automatically, which will call the construtor of its superclass, Object (and Object does have a constructor).

Now suppose we have a class B which extends class A, and it does not provide an explicit constructor, so the compiler automatically supplies it with a default constructor; this default constructor tries to call a constructor from A.

Now why a Compiler Error in B, when the compiler has provided a (default) constructor to A (which is calling Object's constructor, and Object has one)?


EDIT:

Test: Compiles Successfully! Does that mean the last sentence in the tutorial is incorrect?

class A extends B {
    public static void main(String [] args) {
        //A a = new A();
        System.out.println("Yayyy");
    }
}

class B {
}

Solution

  • Firstly some terminology:

    • No-args constructor: a constructor with no parameters;
    • Accessible no-args constructor: a no-args constructor in the superclass visible to the subclass. That means it is either public or protected or, if both classes are in the same package, package access; and
    • Default constructor: the public no-args constructor added by the compiler when there is no explicit constructor in the class.

    So all classes have at least one constructor.

    Subclasses constructors may specify as the first thing they do which constructor in the superclass to invoke before executing the code in the subclass's constructor.

    If the subclass constructor does not specify which superclass constructor to invoke then the compiler will automatically call the accessible no-args constructor in the superclass.

    If the superclass has no no-arg constructor or it isn't accessible then not specifying the superclass constructor to be called (in the subclass constructor) is a compiler error so it must be specified.

    For example:

    public class Base { }
    public class Derived extends Base { }
    

    This is fine because if you add no constructor explicitly Java puts in a public default constructor for you.

    public class Base { }
    public class Derived extends Base { public Derived(int i) { } }
    

    Also fine.

    public class Base { public Base(String s) { } }
    public class Derived extends Base { }
    

    The above is a compilation error as Base has no default constructor.

    public class Base { private Base() { } }
    public class Derived extends Base { }
    

    This is also an error because Base's no-args constructor is private.