我有一个抽象类Employee
,其中有两个具体的子类MinorEmployee
和AdultEmployee
。我知道如何在Employee
中创建静态工厂方法来实例化具体子类的实例:
public abstract class Employee() {
public static Employee create(LocalTime birthdate) {
if (/* omitted */) {
return new MinorEmployee();
} else {
return new AdultEmployee();
}
}
}
在Java中,有没有一种方法可以防止同一包中的调用者直接实例化MinorEmployee
或AdultEmployee
?
我不能将其构造函数设为私有,否则Employee
将无法访问它们。我也不想将它们嵌套在Employee
中。
答案 0 :(得分:2)
尽管有一些警告,但我可以提示您可以尝试的方法
创建一个单独的工厂类,而不是基类。
在工厂类中使构造函数私有化
实例化工厂类中的虚拟私有对象
让MinorEmployee
和AdultEmployee
的唯一构造函数接受工厂类的对象。由于工厂的对象由于私有构造函数而不能存在于类之外,因此几乎没有人可以从外部实例化那些类。
使用伪对象以工厂方法进行传递。
答案 1 :(得分:0)
您可以在MinorEmployee
和AdultEmployee
中将构造函数声明为private
,然后在工厂方法中使用反射:
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
}
}
答案 2 :(得分:0)
另一种方法是:
您可以将构造函数设为私有,并使用辅助方法来标识新实体请求的来源。如果来自您想要的位置,则返回该对象的新实例,否则可以引发和异常。