2013-05-14 69 views
2

当我发现一些不编译的东西时,我正在从另一个包中扩展一个类,即使我认为它应该编译。来自不同实例的Java受保护的方法访问

我有两个类,在不同的包。在包com.foobar.a:

package com.foobar.a; 

public class A { 

    protected void foo1() { 
     System.out.println("foo1() was called!"); 
    } 

    protected static void foo2() { 
     System.out.println("foo2() was called!"); 
    } 

} 

而且在包com.foobar.b:

package com.foobar.b; 

import com.foobar.a.A; 

public class B extends A { 

    public void bar() { 
     A obj = new A(); 
     obj.foo1(); // This doesn't compile 
     A.foo2(); // This does compile 
    } 

} 

现在,根据此:http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html子类必须能够访问方法,即使它不在同一个包中(并且我们看到,该方法是静态的)。事实上,我在Eclipse中进行编程,并且它给我提供了解决此问题的建议,“将foo1()的可见性更改为protected”,但它已受保护。

那么,这里到底发生了什么?在oracle规范中,它使用类,包,子类和世界来指示访问级别。应该添加“实例”到这个列表中,如果是的话,规则是什么?

+0

如果你试图访问'foo1()'直接,而不是使用它作为'obj.foo1()',然后它会工作。 – Logan 2013-05-14 10:32:25

回答

0

this.foo1();会工作,但不会obj.foo1();。在类B内不可见obj.foo1();。唯一可见的foo1()是继承的实际上是this.foo1()。什么是错在这里是要创建的A对象,并试图援引其foo1()。这是预期的行为,protected意味着继承类和同一包中的类可以看到该方法。

+0

如果是这样的话,甚至'A.foo2()'应该产生一个错误,因为'foo2()'和'foo1()'的访问说明符是相同的,唯一的区别是'foo2 )'是'static' – 2013-05-14 09:53:48

+0

*唯一的区别是foo2()是静态的* ==>这就是区别!!!! 'foo2();'或'A.foo2()'指的是相同的方法,'obj.foo1()'和'this.foo1()'是完全不同的调用! – NINCOMPOOP 2013-05-14 10:02:26

3

如果你想在子类中访问此方法,你可以使用它像这样:

public void bar() { 
    this.foo1(); 
} 

创建一个对象,并试图访问受保护的方法是不喜欢访问超类保护的方法。