2010-06-30 301 views
6

我在派生類中創建了基類的實例並試圖訪問受保護的成員。java-protected成員使用基類實例在派生類中訪問

我可以直接訪問派生類中的受保護成員,而無需實例化基類。

基類:

package com.core; 

public class MyCollection { 

     protected Integer intg; 
} 

在同一封裝中派生類 -

package com.core; 

public class MyCollection3 extends MyCollection { 

public void test(){ 

    MyCollection mc = new MyCollection(); 
    mc.intg=1; // Works 
} 
}

在不同的包派生類 -

package secondary; 

import com.core.MyCollection; 

public class MyCollection2 extends MyCollection{ 

public void test(){ 
    MyCollection mc = new MyCollection(); 
    mc.intg = 1; //!!! compile time error - change visibility of "intg" to protected 
} 
} 

如何能夠訪問當派生類也在s中時,派生類中使用基類實例的基類的受保護成員艾米包,但派生類時,不是在不同的包?

如果我將受保護的成員標記爲「靜態」,那麼我可以使用駐留在不同包中的派生類中的基類實例來訪問基類的受保護成員。

+0

可能重複(HTTP:/ /stackoverflow.com/questions/332920/java-protected-access-not-working)---其實這是錯誤的愚蠢!抱歉!這絕對是一個騙局。 – polygenelubricants 2010-06-30 11:25:10

+0

不用擔心,你的IDE不會做出任何差別的問題,因爲這是對Java語言本身的語義。的 – 2010-06-30 11:29:01

+0

可能重複[爲什麼我不能訪問受保護的Java方法甚至以爲我已經擴展的類?(http://stackoverflow.com/questions/1622219/why-cant-i-access-protected-java-method -even-thought-iive-extended-the-class) – starblue 2010-06-30 11:36:27

回答

10

你是對的,你不能這樣做。您無法訪問該字段的原因是,您與課程不在同一個包中,您也不會訪問同一類的繼承成員。

最後一點是關鍵的一個 - 如果你寫

MyCollection2 mc = new MyCollection2(); 
mc.intg = 1; 

那麼這樣的工作,因爲你改變自己類的保護成員(這是目前在該類通過繼承)。但是,對於您的情況,您正試圖在不同的包中更改不同類的受保護成員。因此,您被拒絕訪問應該不會讓您感到意外。

+0

這個解釋真的很容易理解。 我看了一下java語言規範,他們的闡述超過了我的頭! – Tarun 2010-07-01 03:45:28

+0

@Tarun - 如果答案爲你工作,將其標記爲接受(打勾的計票下文) – Bozho 2010-07-01 11:45:50

+0

我不知道這個功能。我會將它標記爲現在回答。 – Tarun 2010-07-02 05:41:05

0

根據Java的成員可訪問性規則,您不能訪問類的受保護成員而不擴展它。

您可以嘗試以下操作。

package secondary; 

import com.core.MyCollection; 

public class MyCollection2 extends MyCollection{ 

public void test(){ 
    intg = 1; 
} 
} 

而不是創建新實例嘗試分配值。它會工作。

+0

同意你的推理 – Tarun 2010-07-01 03:52:54

3

Java tutorial說:

protected修飾符指定的成員只能在其自己的包內訪問(如包私營),此外,它的類的子類在另一個包。

而在你的情況下,你正在訪問另一個對象的變量。巧合的是,它有一個類與當前類相同,但可見性檢查不會檢查該類。

所以,你被拒絕訪問,因爲你是在不同的包第二次,因爲你是在同一個包,你被賦予訪問的第一時間(而不是因爲它的一個子類)

+0

「第一次給予訪問權限,因爲你在同一個包中(而不是因爲它是子類)」 這對我來說很清楚。謝謝。 – Tarun 2010-07-01 03:47:16

1

在總之,這不是真的可能。看起來你應該重新考慮你的設計。

然而,有一個解決辦法,如果你確定這就是你想要做什麼。您可以添加一個受保護的方法MyCollection這需要一個實例,並設置的intg值代表您:

package com.core; 

public class MyCollection { 

    protected Integer intg; 

    protected void setIntg(MyCollection collection, Integer newIntg) { 
     collection.intg = newIntg; 
    } 
}

現在你的子類可以訪問這個方法:

package secondary; 

import com.core.MyCollection; 

public class MyCollection2 extends MyCollection{ 

    public void test(){ 
     MyCollection mc = new MyCollection(); 
     setIntg(mc, 1); 
    } 
}

但請注意,這是一個很奇怪的做法。我會再次建議你在設計這條路線之前需要重新考慮你的設計。

+0

我明白你的觀點。 對我來說,最簡單的方法就是直接訪問受保護的成員,而不是實例化基類並在不同的包中訪問它。 我在玩java的時候「錯誤地」做了它(我不是說我是一個manaul測試人員:-)),然後我的開發人員都沒有能夠提供我想象得到的答案。所以我在這裏發佈。 – Tarun 2010-07-01 03:50:53

0

你不能在派生類訪問受保護變量(它是在不同的包中)如果使用類MyCollection的的一個新的對象進行訪問。 你可以寫intg = 1;的情況下直接製備(新MyCollection的) 這樣的:

package secondary; 
import com.core.MyCollection;  
public class MyCollection2 extends MyCollection{ 

public void test(){ 

    intg = 1; 

} 
} 
3

如果一個類的成員是protected則存在兩種情況:

  1. 如果子類是在相同的封裝
  2. 如果子類是不同包裝

一,同一包裝:
- 可以通過繼承
訪問 - 可以通過創建父類
II的實例訪問。不同的封裝:
- 燦只能通過繼承訪問

請參閱下表爲所有用例:

enter image description here

[Java的保護訪問不工作]的
相關問題