Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can you not inherit from a class whose constructor is private?

Why does Java disallow inheritance from a class whose constructor is private?

like image 787
CodeBlue Avatar asked May 21 '13 03:05

CodeBlue


People also ask

Why we can not inherit constructor?

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.

What happens if parent class constructor is made private?

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.

Can we inherit from a private 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.

Can we extend a class with private constructor?

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.


2 Answers

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.

like image 183
Luiggi Mendoza Avatar answered Nov 16 '22 00:11

Luiggi Mendoza


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.

like image 33
Peter Lawrey Avatar answered Nov 16 '22 00:11

Peter Lawrey