簡體   English   中英

當引用類型為超類時,子類無法訪問超類的受保護方法

[英]Sub-class not able to access the protected method of super-class when the reference is of type super-class

家長班

package p1;

public class A {
    protected void display() {
        System.out.println("Displayed");
    }
}

兒童班(另一個包)

package p2;

import p1.A;

public class B extends A {
    public static void main(String[] args) {
        A a = new B();
        a.display();
    }
}

在子類中,如果我寫B a = new B() ,它工作正常並顯示“顯示”。

但是,在子類中上面的一段代碼,其中A a = new B()被寫入,它會拋出編譯時錯誤,因為'display()' has protected access in 'p1.A'

我現在對受保護的訪問修飾符感到困惑,因為當引用類型是父類時它是如何工作的?

正如我在評論中所寫,你可以這樣做:

package p2;

import p1.A;

public class B extends A {

    public static void main(String[] args) {
        B a = new B();
        a.foo();
    }

    public void foo() {
        display(); // works
        super.display(); // same, but more wordy
        A a = (A)this;
        a.display(); // NOT working !!!
    }

    public void bar(A a) {
        a.display(); // NOT working !!!
    }
}

display() ,可以從子類調用(靜態方法不是成員方法),也可以在同一個包中調用

package p1;

public class C {

    public static void main(String[] args) {
        A a = new A();
        a.display();
    }

}

嗯,那些

a.display(); // NOT working !!!

對我來說不是很清楚,請參閱討論

A a = new B(); 不起作用,因為的引用類型aAA不暴露display()到另一個包。

舉個例子:

public void method(A a){ // defined in some class in a different package
   a.display(); // can't be called from different package as reference type is `A`
}

這里的編譯器沒有辦法知道你是否會分配A或一個亞型的A ,因此它撈出。

如果你忘記你的例子一秒鍾並且只關注我創建的方法會更容易理解,請注意我說它是在不同包中定義的類中。 現在問問自己,我可以從另一個包中調用AA display() ,顯然不是一個受保護的方法。

以下是相關語言規范段落:

如果訪問是通過限定名稱Q.Id或方法引用表達式Q :: Id(第15.13節),其中Q是ExpressionName,則當且僅當表達式Q的類型是S或a時才允許訪問S的子類

6.6.2.1。訪問受保護成員

在你的情況下, QaSB 由於Q的類型不是B的子類,因此不允許訪問。

有關為何引入此限制的說明,請參閱檢查Java虛擬機中受保護成員的訪問權限 (搜索受保護成員的要求

限制受保護訪問的動機是防止幾乎任意訪問受保護的對象成員[Yel02]。 假設m是c中聲明的受保護的非靜態字段。 沒有限制,任何類x都可以使用以下技巧讀取類c的任何對象的字段m的內容:定義c的子類s(該技巧僅在c不是final的情況下有效,因此“幾乎”副詞以上); 在s中聲明一個方法,該方法將類c的對象作為參數並返回其m字段的內容; 並讓x調用此方法。 對受保護訪問的限制可以防止這種情況,因為只有當對象的類o滿足o≤s時,s才能訪問該字段

受保護的方法只能通過包外的子類中的繼承來訪問

每個子類和同一個包中的每個類都可以訪問display

顯示將在同一個包中的每個類都可訪問(如果在不同的包中,則不在子類中可用)

A =新B(); 將無法工作,因為a的引用類型是A和A不會將display()暴露給另一個包。

下面的代碼將起作用:

package p2;

import p1.A;

public class B extends A {
    public static void main(String[] args) {
        B a = new B();
        a.demo();
    }

    public void demo(){
        display();
    }
}

我想從鏈接: http//tutorials.jenkov.com/java/access-modifiers.html重要聲明是

受保護的訪問修飾符提供與默認訪問修飾符相同的訪問權限,並且子類可以訪問超類的受保護方法和成員變量(字段)。

這里,子類僅表示子類引用類型。 對於父引用類型,剩下的唯一選項是public。

這是一種未說明的隱藏規則。 甚至IDE也建議將其更改為public以通過父級的引用進行訪問。 奇怪的!

暫無
暫無

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

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