簡體   English   中英

Java:無法訪問外部類的子類中嵌套類子類的受保護方法

[英]Java: Cannot access protected methods of nested class subclass in subclass of outer class

我正在分解一個類以允許重用,不同的信息隱藏實現等。

它是:

public class Outer
{
    public static class Inner
    {
        // ...
        protected static void innerDoSomething()
        {
            // ...
        }
    }

    public outerDoSomething()
    {
        //...   
        Inner.innerDoSomething();
        //...
    }
}

一切都很好,因為外部的Outer類被允許訪問嵌套的Inner類的受保護成員。

但是嘗試這樣分解:

public class SuperOuter
{
    public static class SuperInner
    {
        // ...
        protected static void innerDoSomething()
        {
            // ...
        }
    }

    // ...
}

public class SubOuter extends SuperOuter
{
    public static class SubInner extends SuperInner
    {
        // ...
        protected static void innerDoSomethingElse()
        {
            // ...
        }
    }

    public outerDoSomething()
    {
        //...   
        SubInner.innerDoSomethingElse(); // OK
        SubInner.innerDoSomething();     // Error: cannnot access!
        //...
    }
}

即使SubOutner可以訪問SubInner的受保護成員,也不能訪問innerDoSomething(),並且SuperInner的所有受保護成員都應該是SubInner受保護接口的一部分。

使它起作用的唯一方法似乎是為每種方法添加顯式委派,例如:

    public static class SubInner extends SuperInner
    {
        // ...
        protected static void innerDoSomethingElse()
        {
            // ...
        }

        protected static void innerDoSomething()
        {
            SuperInner.innerDoSomething();
        }
    }

這很煩人,容易出錯並且浪費時間。 我很想只將innerDoSomething()聲明為public,但這並不是真的正確,因為它只能由SubOuter及其子類使用。

怎么會? SubOuter是否應該禁止並訪問innerDoSomething()保護的訪問並進行訪問?

無法通過變量引用從其他程序包訪問受保護的方法。 如果SuperOuter和SubOuter這兩個類位於同一軟件包中,則它將起作用。

好的,我想我已經解決了,仔細地重新閱讀了Gosling的Java編程語言,第4版

  1. 從邏輯上講,SuperOuter和SubOuter位於不同的程序包中,因此, 沒有一攬子全包保護的成員可訪問性。

  2. 實際上 ,對嵌套類的受保護成員的訪問實際上是作為外部類和嵌套類之間的一種特殊訪問方式 (請參見第5章。嵌套類和接口 )。

  3. 但是,受保護成員的可訪問性並非只是傳遞性的 :除了嵌套/外部授予的形式外,您需要同時處於一個子類中並且具有至少是該子類類型的引用 (即,至少SubXXX,SuperXXX是不夠的) ),因為我引用了第3.5 受保護的真正含義是

每個子類都繼承超類的協定,並以某種方式擴展該協定。 假設一個子類作為其擴展合同的一部分,對超類的受保護成員的值施加了約束。 如果一個不同的子類可以訪問第一個子類的受保護成員,則它可以以破壞第一個子類的契約的方式來操作它們,這不應被允許。

因此,即使在我的情況下xxxInner在邏輯上是xxxOuter的一部分,並且SubOuter擴展了SuperOuter,因此前者在邏輯上應該能夠訪問后者的任何受保護成員,但是SubOuter仍然無法在SuperOuter中訪問SuperInner的受保護成員。如果接收到SuperInner作為參數的自變量,則無法進行相同的處理, 因為該自變量可能屬於完全不同的層次結構分支 在這種情況下,沒有語言規定建立連接。

這也解釋了為什么顯式委派起作用的原因:SubOuter可以訪問SubInner的受保護成員,因為外部/嵌套許可,SubInner可以訪問SuperInner的受保護成員,因為擴展,但是SubOuter無法訪問SuperInner的受保護成員,因為后者實際上可能屬於說到不同的層次結構分支, SubInner的工作就是建立連接

明確的委派在邏輯上和語言定義上都尊重上述所有內容,因此考慮適當的訪問,它應該是“正確的”方法,但是由於冗余(如果我調用SuperInner.innerDoSomethingElse(),這在實現中容易出錯)在SubInner.innerDoSomething()內部?

最終:我可以使用某些python腳本自動化顯式委派(例如,我確實實現了具有類似冗余弱點的Builder模式的自動創建),或者只是放棄了增加訪問控制的安全性並公開了受保護的成員。

暫無
暫無

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

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