2013-05-14 239 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(); 
} 

創建一個對象,並試圖訪問受保護的方法是不喜歡訪問超類保護的方法。