簡體   English   中英

在Java中,為什么超類方法不能從子類實例訪問受保護的或私有的方法/變量?

[英]In Java, why can't a super-class method access protected or private methods/variables from a sub-class instance?

讓我們從另一個行為開始:即使您將方法/變量聲明為私有,同一個類的另一個實例也可以訪問它。 沒關系,我可以忍受它。 我將這些類稱為私有而非實例私有。

現在的問題的一部分:例如,在運行時我希望能夠檢查所有字符串變量this類不為空,如果他們都為空,他們應改為字符串“NULL”。

我可以使用反射來運行變量並獲取它們的值。 但是如果我擴展我的類並添加私有甚至受保護的變量,我的基類就無法訪問它們。 我必須先對變量setAccessible才能使用它們。

所以請向我解釋為什么基類(超類)不能從其子類訪問私有/受保護的變量。 它是它的子類,所以我不明白。 這背后有什么想法?

我知道超類不應該知道它的子類,但在我的例子中它是有意義的,不是嗎?

是因為我不能或不應該以這種方式限制我的子類?


更新:根據答案,我還想知道:為什么不從同一個類訪問另一個實例的私有變量被視為違反封裝?

這很簡單,因為它違反了封裝。 另一堂課不應該進入你的班級,並且要亂搞一些事情,即使你把這個課程概括。 例如,車輛如何了解汽車的任何信息? 基類的重點是提供子類,但是像過度保護的父類一樣,你所建議的內容太多了。

要回答您的更新問題(因為原始問題已得到很好的回答),私有的目的是隱藏實現細節,以便這些實現細節不會成為依賴關系。 這是面向對象編程的本質 - 封裝確保通過將不同部分隔離到自己的區域來保持復雜性。

由於類知道它自己的實現 - 它定義了它,因此限制對其他實例的訪問沒有任何好處,因為類實現聲明它已經暴露給所有這些細節的所有私有實例。

在這種情況下隱藏它實際上會增加復雜性,因為您必須添加額外的訪問級別以允許類級別可見性而不是實例級別可見性,而不實際封裝任何進一步的復雜性。

這都是關於繼承和封裝的。

Java的可見性規則說明了這一點

  1. 私有成員只能在定義它們的類中訪問
  2. 受保護的成員只能訪問
    • 定義它們的類
    • 定義它們的類的子類
    • 與定義它們的類在同一個包中的其他類

當然,正如您所提到的,在反射中您可以更改規則(除非SecurityManager禁止它)

我傾向於從務實和現實的角度來看待它:

public class Test1 {
    private int a = 1;

    public static void main(String s[]) {
        System.out.println((new Test1()).a);
        System.out.println((new Test1()).getA());
        System.out.println((new Test2()).getA());
    }

    public int getA() { return a; }
}

class Test2 extends Test {
    private int a = 2;

    public int getA() { return a; }
}

您建議Test1使用什么語法來訪問Test2私有成員a 寫入Test1Test2可能甚至不存在。

同樣,基類(超類)不知道它何時被繼承。 要允許基類知道何時繼承它,您必須能夠在繼承基類時修改它。 你建議我在寫作時以某種方式修改我的ArrayList本地副本:

class MyArrayList extends ArrayList

當我決定在你的計算機上運行我的代碼的那一天會發生什么,你是否得到了我知道MyArrayListArrayList修改副本,或者我是否以某種方式修改了你計算機上的副本?

能以某種方式克服這些問題嗎? 當然。 允許它有什么價值嗎? 沒有我能看到的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM