这是一个例子:
class A
{
List l = new List ();
list.insert("x");
}
class List
{
...
public void insert ()
{
/*insertion occurs*/
}
...
}
是否有可能将 insert() 方法保持为公共状态,但仅限制对类 A 的访问,以便只有在从 A 调用时,其他类才能访问它?
我会将调用该方法的对象作为参数传递,即
list.insert("x", this);
然后检查传递的Object是否是A类的Instance
public void insert (String x, Object o)
{
if(o instanceof ClassA){
/*insertion occurs*/
}
}
如果方法是公开的,那么每个人都可以访问它。像您这样访问控制的技巧是通过接口公开一组公共操作,将辅助操作添加到实现接口的私有类,并使您的用户编程到接口,而不是类。
这是一个例子:
public interface MyList {
Object elementAt(int i);
}
public class A {
private static class MyListImpl implements MyList {
public Object elementAt(int i) {
...
}
public void insert(Object element) {
...
}
}
private final MyListImpl list = new MyListImpl();
public MyList getList() { return list; }
public void insert(Object o) { list.insert(o); }
}
使用场景:
A a = new A();
a.insert(123);
a.insert("quick brown fox");
MyList lst = a.getList();
System.out.println(lst.elementAt(0));
System.out.println(lst.elementAt(1));
是的,您可以将调用对象作为参数传递,并在实际代码之前检查 insert() 方法。
public void insert(Object obj){
if(obj instanceof A){
//your code block
}
}
请注意,这将允许所有扩展 A 的类也可以调用 insert。如果您只想限制 A 类,请添加附加检查。
public void insert(Object obj){
if((obj instanceof A) && obj.getClass().getSimpleName().equals("A")){
//your code block
}
}
我们也可以仅使用条件“obj.getClass().getSimpleName().equals(“A”)”来实现第二种情况。
使用访问修饰符可以做的最好的事情是使方法包私有(删除public
关键字)并仅将这两个类保留在同一个包中。
package problems;
public class Problem1 {
public static void main(String[] args) {
B b = new B();
b.methodInB();
C c = new C();
c.methodNotInB();
}
}
class A {
public void onlyB() {
StackTraceElement[] stackTraceElements = Thread.currentThread()
.getStackTrace();
if (!problems.B.class.getCanonicalName().equals(
stackTraceElements[stackTraceElements.length - 2]
.getClassName())) {
System.err.println("You are not authorized to call me!!");
return;
}
System.out.println("You are authorized to call me!!");
}
}
class B {
public void methodInB() {
A a = new A();
a.onlyB();
}
}
class C {
public void methodNotInB() {
A a = new A();
a.onlyB();
}
}
如果前面的答案中的所有“内部类”内容都让您感到困惑,那么还有另一种可能更直观的方法(假设您已经了解了extends
关键字和继承)。您可以简单地制作insert()
方法protected
而不是public
制作class A
扩展List
。例如:
public class List {
...
protected void insert() {
//insertion occurs
}
...
}
public class A extends List {
...
}
只要没有其他类扩展 List,只有类型的对象A
才能List
使用该insert()
方法。
把它作为内部类放在 A 中,或者你可以做另一件事......让 insert 接受一个类型为 Object 的参数,并在它的开头检查参数的类型是否为 A .... 当你调用它时发送调用对象......也许这不是一个好主意,但它会做你想做的事
将其放入允许的类并使其私有。