2011-07-29 69 views
3

這是中的示例Java™SCJP認證程序員指南綜合入門 - 第三版 - Khalid A. Mughal Rolf W. Rasmussen我無法理解。無法訪問也是子類的子類中的受保護成員

我知道如果我們沒有將它繼承到另一個包中定義的子類中,我們就無法訪問受保護的成員。

但我仍不明白爲什麼我們無法從子類的子類訪問它。

的例子如下

A.java
package packageA; 
public class A { 
    protected int z; 
} 

B.java
package packageB; 

import packageA.A; 

public class B extends A { 

    void action(A obj1, B obj2, C obj3) { 
     z = 10;  // z in B - Works 
     obj1.z = 10; // Won't work for obvious reason 
     obj2.z = 10; // z in B - Works 
     obj3.z = 10; // z in C - Works 

    } 
} 

class C extends B { 

    void action(A obj1, B obj2) { 
     z = 10; // Works 
     obj1.z = 10; // Won't work for obvious reason 
     obj2.z = 10; // z in B - WHY DOESN'T THIS WORK????? 

    } 
} 
+0

這是一個學術活動,還是你真的想要寫這樣的代碼? – jiggy

+0

@jiggy這是一個例子** Java程序員指南SCJP認證全面入門第三版Khalid A. Mughal Rolf W. Rasmussen **我無法理解。 –

+0

我當然希望作者不要使用諸如'A','B'等類名的例子。如果他們這樣做,不是很直觀! – Joeblackdev

回答

3

目前接受的答案不回答問題。它解釋了爲什麼您不能從BC的主體內訪問A實例的成員z。但問題是,您爲什麼不能從C內訪問B實例的成員z

原因是B不是C的子類。閱讀Java規範,第6.6.2.1節:

讓C爲聲明受保護成員的類。訪問只內C.

另外的一個子類S的體允許的,並且,當ID表示一個實例字段或實例方法,則:

如果接入是由有資格的名稱Q.Id ,其中Q是ExpressionName,則訪問被允許,當且僅當表達式Q的類型是S或S的

http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.2.1

一個子類

(加粗礦)

左右的時間內B你可以說obj3.z因爲obj3C類型,CB一個子類。

但內C你不能說obj2.z,因爲obj2B型和BC一個子類。


總結的保護意義:

假設一個受保護的成員A類的主體內聲明。

(1)您可以從包含A的包中的任何位置訪問受保護的成員。

(2)另外,一個子類的AS,在不同的包中定義,可以訪問該繼承S但不能在類的實例的S實例或類的實例的保護構件,其從S繼承。

最後一節是回答這個問題的關鍵。

1

受保護成員可以通過在那裏的聲明的類的子類進行訪問相同包作爲聲明受保護成員的類。您的案例中的類B和C在不同的包中聲明爲類A的類。這就是爲什麼您不能通過對類A的引用訪問'z'。如果您將類B和C移入與A相同的包,將工作。

這就是爲什麼你不能訪問類C中的obj2.z,因爲'z'是在不同包中的類中聲明的。

+0

這是否意味着成員訪問不會在第二個子類中繼承? –

+0

我想我不會像編譯器那樣思考。 –

+1

如果您正在爲SCJP學習(正如我所做的那樣),那麼當您看到受保護的成員時,請考慮「Package and Kids」以進入。換句話說,只有同一個包中的子類和類纔可以訪問受保護的成員。這項研究祝你好運。 – Joeblackdev

相關問題