Reputation: 4349
I have no doubt this has been asked and answered here a dozen times, but I just can't find a satisfactory answer.
I have a family of classes that I only want instantiated by the abstract parent class through a static method like this (I probably have typos here I am typing without trying to compile).
public abstract class Papa {
public static Papa newInstance() {
String strClass = Papa.figureOutTheNameOfChildClassToInstantiate();
Papa papa = (Papa) Class.forName(strClass).newInstance();
return papa;
}
public abstract void doSomething();
...
}
public class Child extends Papa {
public void doSomething() { /* Do something */ }
}
That's more or less what I have now. What I wish to do is be sure that the Child can only be instantiated by the factory method Papa.newInstance(). I tried to do this by making the Child's no-argument constructor private, but then Papa can't instantiate it.
So, my question is, how can I make sure Child instances are only created by the factory method Papa.newInstance()?
Upvotes: 2
Views: 1935
Reputation: 86403
A couple of possible alternatives:
Use the default visibility for the child class constructors and put them in the same package as the parent class. This has the disadvantage that those classes can be instantiated by any other class in the same package, including any "sibling" classes.
Have all child classes as nested classes in the parent class. Marking them as private static
would make them visible only to the parent class. Unfortunately, this also implies having the code of all classes in the same file...
Upvotes: 3
Reputation: 47233
If you absolutely, positively, want to enforce this, then give Papa
a protected constructor which takes a parameter of type Xyzzy
. Make Xyzzy
a protected inner class in Papa
. Give it a private constructor. Now, only Papa
can make instances of Xyzzy
. Since you need an instance of Xyzzy
to call Papa
's constructor, and since subclasses of Papa
must call its constructor from their constructors, you need an instance of Xyzzy
to call the constructor of any subclass of Papa
. Hence, only Papa
can call the constructors of its subclasses. Even though Xyzzy
doesn't do anything.
Subclasses could leak their Xyzzy
instance, which would allow other code to call subclass constructors. But you can constrain that too, by making Xyzzy
single-use, and only so within the context of a single static factory invocation.
But to be honest, i wouldn't bother!
Upvotes: 4