views:

1537

answers:

4

As an example:

public class Foo {
    private Foo() {}
}

public class Bar extends Foo {
    private Bar() {}

    static public doSomething() {
    }
}

That's a compilation error right there. A class needs to, at least, implicitly call its superclass's default constructor, which in this case is isn't visible in Foo.

Can I call Object's constructor from Bar instead?

+7  A: 

You can't. You need to make Foo's constructor package private at the very least (Though I'd probably just make it protected.

(Edit - Comments in this post make a good point)

Richie_W
Package-private is sufficient, if both are put in the same package.
starblue
@starblue - I believe that's why he said 'at the very least'.
Ryan Thames
package is more restrictive that protected, so 'at the very least' is wrong. If both were in the same outer class, I think the private construct would be accessible.
Tom Hawtin - tackline
@Tom - Whoops, my bad :P
Ryan Thames
+1  A: 

You won't be able to create an instance of Bar for as long as Foo has a private constructor. The only way you would be able to do it is if Foo had a protected constructor.

Phill Sacre
If a superclass has a private constructor, then the subclass won't even compile.
Rob Williams
A: 

You can't call Object's constructor directly from Bar while it's a subclass of Foo, it would have to through Foo's constructor, which is private in this case.

When you declare Foo's constructor private, it does not create a default public constructor. Since Bar has to invoke Foo's constructor, it is not possible to leave it private. I would suggest, as others have, on using protected instead of private.

Ryan Thames
+4  A: 

This is actually a symptom of a bad form of inheritance, called implementation inheritance. Either the original class wasn't designed to be inherited, and thus chose to use a private constructor, or that the entire API is poorly designed.

The fix for this isn't to figure out a way to inherit, but to see if you can compose the object instead of inheriting, and do so via interfaces. I.e., class Foo is now interface Foo, with a FooImpl. Then interface bar can extend Foo, with a BarImpl, which has no relation to FooImpl.

Inside BarImpl, you could if you wish to do some code reuse, have a FooImpl inside as a member, but that's entirely up to the implementation, and will not be exposed.

Chii