【发布时间】:2013-01-16 19:33:01
【问题描述】:
假设我有 3 节课
class1、class2 和 class3。
我怎样才能让class1 只能被class2 (class1 object = new class1()) 实例化,而不能被 class3 或任何其他类实例化?
我认为它应该与修饰符一起使用,但我不确定。
【问题讨论】:
-
您是否需要
class1才能被其他类访问,只是无法被实例化?
假设我有 3 节课
class1、class2 和 class3。
我怎样才能让class1 只能被class2 (class1 object = new class1()) 实例化,而不能被 class3 或任何其他类实例化?
我认为它应该与修饰符一起使用,但我不确定。
【问题讨论】:
class1 才能被其他类访问,只是无法被实例化?
我想将您的课程重命名为 Friend、Shy 和 Stranger。 Friend 应该能够创建 Shy,但 Stranger 应该不能。
此代码将编译:
package com.sandbox;
public class Friend {
public void createShy() {
Shy shy = new Shy();
}
private static class Shy {
}
}
但这段代码不会:
package com.sandbox;
public class Stranger {
public void createShy() {
Friend.Shy shy = new Friend.Shy();
}
}
此外,如果我们创建一个名为FriendsChild 的新类,则此也不会编译:
package com.sandbox;
public class FriendsChild extends Friend {
public void childCreateShy() {
Shy shy = new Shy();
}
}
仔细想想,这种命名约定是有道理的。仅仅因为我是某人的朋友并不意味着我的孩子认识他们。
请注意,所有这些类都在同一个包中。据我所知,这是您正在寻找的场景。
【讨论】:
除了使构造函数受保护之外的另一个选择:
class1 构造函数设为私有class2 的有效实例才能返回class1 的实例【讨论】:
使class1成为class2的内部类。
【讨论】:
更新
制作protected 构造函数并将符合条件的类放在同一个包中,如果您希望包外的任何类来构造此实例,那么在此示例中您需要该类扩展ClassA,
如果您对其进行限制,请使用default 访问说明符
package com.somthing.a;
public class ClassA {
ClassA() {
super();
// TODO Auto-generated constructor stub
}
}
package com.something.a;
public class ClassB {
public static void main(String[] args) {
new ClassA();//valid
}
}
package com.something.c;
public class ClassC {
public static void main(String[] args) {
new ClassA();// invalid
}
}
【讨论】: