2016-10-17 75 views
2

我被給了一個問題來確定以下訪問是否合法。受保護字段外部包的Java訪問控制

package SomePack; 

public class A1 { 
    ... 
protected int y1; 
} 

/////////// 

package Whatever; 
class B2 extends A1 { 
    void h(SomePack.A1 x) { 
     x.y1 = 3; // Is this line legal? 
    } 
} 

我想這大概是合法的,因爲 1. Y1場protectedextendsA1所以B2是A1的亞型。 3.訪問控制基於靜態類型,x的靜態類型爲A1。

但面試官說答案應該是非法的。任何人都可以解釋這一點?非常感謝。

+2

這將幫助[控制對類的成員的訪問](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html) –

+0

恕我直言,正確的採訪答案是:「它不編譯它的事情,不應該首先完成!「 –

回答

0

protected構件或構造方法的對象可以從它僅由代碼中聲明的封裝,外部訪問負責執行對象

看到https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.1

實施例6.6-1。訪問控制:

package points; 
public class Point { 
    protected int x, y; 
    public void move(int dx, int dy) { x += dx; y += dy; } 
    public int getX() { return x; } 
    public int getY() { return y; } 
} 

字段x和y的聲明保護,並且是包點外部訪問僅在Point類的子類,而只有當他們正在通過代碼實現的對象領域即訪問它們。

所以在B2類,它可以訪問的本身或B2對象y1,但不能訪問的SomePack.A1 x或任何其他A1的子類的對象y1

+0

謝謝。如何解釋這句話:'只有當它們是正在訪問它們的代碼正在實現的對象的字段時。 ?' –

+0

@FongTinyik這意味着如果使用'x'和'y'的代碼也是實現相應子類的代碼,則可以在包外部訪問'x'和'y'。 – locoyou

+0

實現「相應子類」的代碼只能訪問「相應子類」的(對象)的「x」,「y」。 – locoyou

-1
  • A protected成員只能在子類之外的包之外訪問。
  • 如果您需要訪問protected成員變量外包,它只需要通過繼承來訪問。
  • 如果需要使用引用變量訪問它,它需要位於同一個包中。

下面的例子將在上面進行闡述。

當您修改成員變量爲protected時,那麼受保護的成員變量只能通過繼承在包外部訪問。

聲明x.y1 = 3;它試圖訪問使用引用變量,這是外部包不可能的。

如果你想訪問它,只需使它y1 = 3

使用下面的代碼應該使您能夠訪問Y1

package whatever; 

import somepack.A1; 

class B2 extends A1 { 
    void h(somepack.A1 x) { 
     System.out.println(y1); 
     y1 = 3; 
     System.out.println(y1); 

    } 

    public static void main(String args[]){ 
     B2 obj = new B2(); 
     obj.h(new A1()); 
    } 
} 

下文將對此進行打印。

0 
3 

因此,您可以看到我們可以直接使用繼承將值分配給受保護的成員。

現在讓我們看看如何使用引用變量類型(即無繼承)來訪問。

package somepack; 


public class A1 { 
    protected int y1; 

} 
class C{ 
    public static void main(String args[]){ 
     A1 obj = new A1(); 
     System.out.println(obj.y1); 
    } 

} 
+0

如果我想更改'x'的y1字段,該怎麼辦? –

+0

我們已經在做它。請檢查更新的代碼。 –

+0

感謝Prasad並祝賀10k。但我的問題是爲什麼不能訪問'x'的'y1'字段,而不是如何訪問'this'的'y1'。 –

0

受保護的修飾符用於繼承,對於包可見性只使用無修飾符。

這裏是什麼樣的不同的可見旨在爲

public修改的簡要說明用於在需要時能見度無處不在:當你想要的類的內容

public void someMethod(){ 
    //user code here 
} 

protected改性劑通過繼承可訪問:

protected void someMethod(){ 
    //user code here 
} 

當您想要p時不使用修飾符只有ackage知名度:

void someMethod(){ 
    //user code here 
} 

最後private是當你想不可見,只希望在內部使用它。

private void someMethod(){ 
    //user code here 
} 

對於上述我要提到的一個更詳細的解釋:Controlling Access to Members of a Class