1. 程式人生 > >父類私有變數是否被子類繼承

父類私有變數是否被子類繼承

因為網上就父類私有屬性是否被子類繼承一直爭論不休,以下為了解釋清楚,本人做了大量詳細說明,請不要嫌我囉嗦都是基礎的知識認真看完你會明白的

class Parent{//父類

    private int a = 1;//私有許可權
    public int b = 1; //公有許可權

public int getA() {
     return a;
}

public int getB() {
    return b;
}
    
}


public class Son extends Parent{//子類繼承父類

     int b =2;

}




class Demo{

public static void main
(String[] args) {
Son son = new Son();

System.out.println(son.getA());//結果為 1

System.out.println(son.getB());//結果為 1

                //列印結果為都是 1

針對此結果:1>如果說不能繼承私有變數,那子類沒有變數a那如何能打印出變數 a 的結果

                      2>如果單純的認為繼承就是父類的東西已經被子類拿到了,屬於子類了。那我們知道子類和父類存在同樣的變數時,會被子類覆蓋。那                            為何結果不是 2,反而是 1 呢?

答案是:子類的繼承實際是裡面包含了一個super域,當子類物件呼叫一個子類沒有的方法getA()時(我們並沒有複寫),它先在自己的直屬空間找,找不到的話,會呼叫super域的getA()方法super域也就是我們說的父類)。而super域中的方法只操作自己的變數和方法,子類變數和方法是無法操作的。所以結果都是1.

因為子類物件呼叫方法和屬性是有優先順序的,優先呼叫自己直屬屬性和方法。如果自己沒有,那麼就會呼叫super域的方法和屬性(比如當子類的方法操作了一個變數,如果子類沒有,它會向super域中去找)。不要誤認為super域中的所有欄位都是被子類繼承,子類和父類都有一份這個被繼承的變數。其實是子類間接有的,不是直接有的,子類所擁有的

super域(父類)。   

覆蓋的原理就顯而易見了,如果操作子類的方法,那麼就會在子類變數中去找,如果子類存在此變數,就不會去super域中去找了。不是像IO流那樣真正的覆蓋,只是不會去super域中去找而已,super域中同名的欄位依然安全的存在。

        所以這才是真正的繼承!  以下為原理圖,作參考!


那麼子類繼承了父類私有屬性嗎?

這個問題官方原文是這樣的:

A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.

最後解釋:為何很多人認為子類不能繼承父類的私有屬性,因為老大都這麼說了嘛!!!但請注意老大同時也說了,如果父類中有get或者set方法時,子類也可以拿到父類的私有屬性。其實要按記憶體角度說也是繼承的,因為它確實也存在於記憶體的子類物件的super域中,只是子類看不見而已。其實sun公司說的不繼承,是當子類繼承父類時,如果子類看不到父類的屬性,那麼就認為是不繼承的,沒有說子類物件中不存在父類的私有屬性