1. 程式人生 > >隱身衣揭祕--java中繼承/隱藏/覆寫

隱身衣揭祕--java中繼承/隱藏/覆寫

故事背景

看過《哈利·波特》的娃們,想必一定還記得電影中的“隱形斗篷”。。這件隱形衣是哈利收到的聖誕禮物,也是死亡聖器中的三件套之一,它讓哈利小盆友在執行任務的過程中簡直是如虎添翼!

 

其實說白了,隱身衣所包裹的就是人類本能的掌控欲與窺探欲,我們渴望知道和了解所有事,但很多時候又不想讓別人知道,所以我們需要“隱身衣”。。

 

 繼承Inheritance/隱藏hide/覆寫override

java中有繼承Inheritance/隱藏hide/覆寫override的概念,我們暫且不管他們的區別,先看看最近發生的一件小事,boss在開會時說錯了一個數字,Leader趕緊說:”那是我弄錯的“,程式猿想找到Boss說的數字時,卻怎麼也不行,這是怎麼回事呢?請看案情回放:

public class Conference {
    public static void main(String[] args) {
        System.out.println(new Leader().sales);
    }
}
class Boss {
    public Integer sales=10000;
}
class Leader extends Boss{
    private Integer sales=9000;
}

咋一看,會列印Leader的銷售量資料9000,但仔細分析來看,Leader類的sales變數是私有的,程式不能編譯通過。該程式確實不能編譯,但是錯誤出在Conference類中。原因:在Conference中呼叫的是new Leader()即leader的例項,不是Leader類,一個覆寫方法的訪問修飾符所提供的訪問許可權與被覆寫方法的訪問修飾符所提供的訪問許可權相比,至少要一樣多[JLS 8.4.8.3]。

因為sales是一個域,所以Leader.sales隱藏(hide)了Boss.sales,而不是覆蓋了它[JLS 8.3]。對一個域來說,當它要隱藏另一個域時,如果隱藏域的訪問修飾符提供的訪問許可權比被隱藏域的少,儘管這麼做不可取的,但是它確實是合法的。

其實我們還是可以找到老闆的所說的sales的。如下:

public class Conference {
    public static void main(String[] args) {
        System.out.println(((Boss)new Leader()).sales);
    }
}
class Boss {
    public Integer sales=10000;
}
class Leader extends Boss{
    private Integer sales=9000;
}

總結

覆寫與隱藏之間的一個非常大的區別。一旦一個方法在子類中被覆寫,你就不能在子類的例項上呼叫它了(除了在子類內部,通過使用super 關鍵字來方法)。然而,你可以通過將子類例項轉型為某個超類型別來訪問到被隱藏的域,在這個超類中該域未被隱藏。

參考資料

【1】java解惑

【2】https://www.sohu.com/a/231064552_76