如果我们有类 A 和 B,并且类 A 的构造函数是私有的,并且我们想在 B 中使用 A 的实例,该怎么做?我看到一个答案说“提供允许访问从类中创建的实例的静态方法或变量”,但我不明白这一点。
6 回答
您寻求的代码模式称为工厂方法。
该类提供了一个静态方法,该方法返回其自己的类的实例。私有构造函数对类的所有方法(包括静态方法)都是可见的,因此静态方法可以代表调用者调用私有构造函数。
下面是这个模式的一个例子:
public class A {
private A() {
}
public static A create() {
return new A();
}
}
这通常与Singleton Pattern结合使用,这会将上面的示例更改为:
public class A {
private static A INSTANCE = new A();
private A() {
}
public static A getInstance() {
return INSTANCE;
}
}
A 需要有一个提供类 A 实例的公共方法,例如:
class A {
/*Constructors and other methods omitted*/
public static A getInstance() {
return new A();
}
}
或者,如果 B 是 A 的内部类(反之亦然),则 B 可以直接引用构造函数,例如:
public class A {
private A() {}
public static class B {
private A instanceOfA = new A();
public B() {}
}
}
一个只有私有构造函数的类被设计成其他类不能直接实例化它。这大概是有充分理由的。该类可以提供一个工厂方法来实例化该类……或获取该类的现有实例。
如果需要更改设计,最好的方法是修改类;例如,通过使构造函数可见,或通过添加工厂方法。如果你不能这样做,我认为可以使用反射来打破可见性规则并使用私有构造函数创建一个实例。但是,我只会将其作为最后的手段......而不是在仔细分析整个应用程序的后果之前。
私有构造函数旨在使类没有任何实例。但是可以使用super()从子类访问内容。实现是这样的:
公共类 ClassA {
私有 int val;
私人类A(int val)
{this.val = val;
}
public int getVal() { return val;
}
}
公共类 ClassB 扩展 ClassA {
公共 ClassB(int val) { super(val); } }
...
B 类 b = 新 B 类(4);
System.out.println("b 的值:" + b.getVal());