6
votes

Since an abstract class cannot be instantiated, and since protected members are always visible to subclasses, it would seem that it makes no difference whether its constructors are public or protected.

Is there any example where a public constructor could make a difference compared to a protected one? I would normally prefer the most restrictive access level which is applicable.

2
The answer depends on the needs of the class. You might have more than one Abstract implementation of the class which provides basic configuration, but needs one or more methods to be implemented by the concrete class. This could be done to reduce the amount of repetition that might be need to implement your base abstract class, for example...MadProgrammer
I would say since both public and protected constructors are guaranteed to behave the same way it is preferable to use the less confusing one (public) since some people (especially beginners) have problem with understanding what protected means. But that is just my opinion. Also it may be harder to miss while generating documentation.Pshemo

2 Answers

8
votes

No, there is no good reason to make a public constructor for an abstract class: you cannot instantiate your abstract class without subclassing it first, and the language deals with the relevant corner cases for you.

In particular, if you are to subclass your abstract class anonymously, meaning that you are unable to provide your own constructor in the subclass, the language would provide one for you based on the signature of the protected constructor of your abstract base class:

abstract class Foo {
    protected int x;
    protected Foo(int x) {this.x = x;}
    public abstract void bar();
}
public static void main (String[] args) {
    Foo foo = new Foo(123) { // <<== This works because of "compiler magic"
        public void bar() {System.out.println("hi "+x);}
    };
    foo.bar();
}

In the example above it looks like the protected constructor of an abstract class is invoked, but that is not so: the compiler builds a visible constructor for your anonymous class*, which is what gets invoked when you write new Foo(123).

Demo.

* The actual visibility is default. Thanks, Pshemo, for spotting the error and supplying a nice test example.

0
votes

There is really no point in making constructor of abstract class public. But you can be sure, that nobody will create instance directly.