Reputation: 6815
I have an abstract class Employee
with two concrete subclasses, MinorEmployee
and AdultEmployee
. I know how to create a static factory method in Employee
that instantiates an instance of a concrete subclass:
public abstract class Employee() {
public static Employee create(LocalTime birthdate) {
if (/* omitted */) {
return new MinorEmployee();
} else {
return new AdultEmployee();
}
}
}
Is there a way in Java to prevent a caller in the same package from directly instantiating a MinorEmployee
or AdultEmployee
?
I can't make their constructors private, or Employee
wouldn't be able to access them. I also don't want to nest them inside of Employee
.
Upvotes: 4
Views: 374
Reputation: 129
Another way is:
You can make the constructors private and use an auxiliary method to identify from where the request of new entity is coming. If is coming from where you want, return a new instance of the object else, you can throw and an exception.
how to figure out what class called a method in java?
Upvotes: 0
Reputation: 6622
I can give you hint on something you can try, though there can be some caveats:
create a separate factory class instead of base class.
make the constructor private in the the factory class
instantiate a dummy private object in the factory class
Let MinorEmployee
and AdultEmployee
's only constructor accept object of factory class. Since object of factory can not exist out side the class due to private constructor, practically no one else should be able to instantiate those classes from outside.
Use the dummy object to pass on in your factory method.
Upvotes: 2
Reputation: 9648
You could declare the constructors in MinorEmployee
and AdultEmployee
as private
and then use reflection in your factory method:
public static Employee create(LocalTime birthdate) {
try {
Class<? extends Employee> clazz;
if (omitted) {
clazz = MinorEmployee.class;
} else {
clazz = AdultEmployee.class;
}
Constructor<? extends Employee> cons = clazz.getConstructor();
cons.setAccessible(true);
return cons.newInstance();
} catch (NoSuchMethodException | SecurityException
| InstantiationException | IllegalAccessException
| InvocationTargetException ex) {
// handle the exception
}
}
Upvotes: 0