Java – Use cases of a default sub class constructor that doesn't add any functionality?

Advertisements

I have an abstract Book class:

public abstract class Book {

    private String description;

    protected Book() {}

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

}

And a sub class:

public class Novel extends Book{}

Is there any advantage in adding the following default constructor to my book class:

public class Novel extends Book {

    public Novel() {
        super();
    }
}

>Solution :

It makes literally no difference, given that:

  • ALL classes MUST have a constructor. If you fail to add one, java will make one for you. It will be public, it will have no arguments, and it will do nothing.

  • ALL constructors MUST either call super() or call this(), on the first line1 no exceptions. If you fail to do this, java will make this call for you. It will inject super();.

  • These rules apply to each other – that empty constructor javac makes for you will therefore contain, effectively, super();.

  • super() is not necessarily legal: If your parent class does not have a no-args constructor, it wouldn’t be. In such a case, failure to write any constructor is therefore a compiler error (because javac makes one for you that is empty, i.e. has super();, which would be invalid.

Writing public MyClass() { super(); } in any class is therefore utterly pointless. You might as well put import java.lang.*; at the top of a source file (java does that for you too). There is only a point to adding such a constructor if there is also another constructor.

The super(); is useless in any case. Useless in the sense of ‘if you get rid of it, the class file produced by javac would be bit for bit identical save for the line number table). One may make the argument that adding it makes for ‘clearer code’ but this is a highly dubious practice (that is, the practice of adding explicitly things that javac will automate for you, that’s a slippery slope. Do you ban automatic widening conversions? Calling methods on the result of methods? Disallow var? Never use try-with? That line of thinking taken to its logical conclusion leads to a farce).

NB: The fact that your superclass’s no-args constructor is protected makes no difference; failure to provide any constructor in the subclass means you get a public one that just calls super().

[1] There is talk of waiving this restriction. You’ll still have to call it, but there may be certain statements that can precede it. Possibly coming to JDK21, probably later, possibly never.

Leave a ReplyCancel reply