Why does Java disallow inheritance from a class whose constructor is private?
In simple words, a constructor cannot be inherited, since in subclasses it has a different name (the name of the subclass). Methods, instead, are inherited with "the same name" and can be used.
A private constructor in Java is used in restricting object creation. It is a special instance constructor used in static member-only classes. If a constructor is declared as private, then its objects are only accessible from within the declared class. You cannot access its objects from outside the constructor class.
Members of a class that are declared private are not inherited by subclasses of that class. Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared. The answer is No. They do not.
When you have a class with only private constructors, you can also change the class to final because it can't be extended at all.
Because a class must call its super class constructor always. If the super class constructor can't be accessed, then the sub class can't be initialized.
More info: JLS 8.8.10. Preventing Instantiation of a Class
Regarding Brian Roach's comments:
The call [to the parent class constructor] is only implicit if you don't do it explicitly and the parent has a public or protected no-arg constructor (or hasn't defined any in which case there's a default no-arg). It's required because ... that's how the language works. Children [classes] must call [their] parent's constructor.
Note that when you instantiate any class in Java, there's always a implicit call to Object
constructor since it is the super class of all classes. It will execute its default constructor:
public Object() {
}
Note from the JLS link:
It is a compile-time error if a default constructor is implicitly declared but the superclass does not have an accessible constructor (§6.6) that takes no arguments and has no throws clause.
Java doesn't prevent sub-classing of class with private constructors.
public class Main {
static class A {
private A() {
System.out.println("Subclassed A in "+getClass().getName());
}
}
static class B extends A {
public B() {
}
}
public static void main(String... ignored) {
new B();
}
}
prints
Subclassed A in Main$B
What it prevents is sub-classes which cannot access any constructors of its super class. This means a private constructor cannot be used in another class file, and a package local constructor cannot be used in another package.
In this situation, the only option you have is delegation. You need to call a factory method to create an instance of the "super" class and wrap it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With