Java中子類能不能繼承父類的私有變量和方法?

以下所有觀點只有官方標準爲準,其餘涉及的觀點皆是對這個話題的補充討論

一、觀點引出:

觀點一: 官方文檔的解釋(標準)
      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. "
      A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.
詳細鏈接:https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

意思是說:子類不繼承private其父類的成員。但是,如果超類具有用於訪問其私有字段的公共或受保護的方法,則子類也可以使用這些方法。嵌套類可以訪問其封閉類的所有私有成員,包括字段和方法。因此,子類繼承的公共或受保護的嵌套類可以間接訪問超類的所有私有成員

這是官方的觀點,當然有人就有其他的理解

觀點二: 父類的任何成員變量都是會被子類繼承下去的。子類繼承父類,子類擁有了父類的所有屬性和方法。父類的私有屬性和方法子類是無法直接訪問的。當然私有屬性可以通過public修飾的get和set方法訪問到的,但是私有方法不行。父類的private屬性,會被繼承並且初始化在子類父對象中,只不過對外不可見。
  詳解:分析內存後,會發現,當一個子類被實例化的時候,默認會先調用父類的構造方法對父類進行初始化,即在內存中創建一個父類對象,然後再父類對象的外部放上子類獨有的屬性,兩者合起來成爲一個子類的對象。
  所以:子類繼承了父類的所有屬性和方法或子類擁有父類的所有屬性和方法是對的,只不過父類的私有屬性和方法,子類是無法直接訪到的。即只是擁有,但是無法使用。 (這裏不考慮Java反射機制)


二、辨析:

從繼承的概念來說,private和final不被繼承。Java官方文檔上是這麼說的。

從內存的角度來說,父類的一切都被繼承(從父類構造方法被調用就知道了,因爲new一個對象,就會調用構造方法,子類被new的時候就會調用父類的構造方法,所以從內存的角度來說,子類擁有一個完整的父類)。子類對象所引用的內存有父類變量的一份拷貝。
  如圖所示,父類爲Person類,子類爲Student類。首先明確子類不能繼承父類的構造方法。這就是爲什麼子類的默認的構造方法會自動調用父類的默認的構造方法。
  在子類的構造方法中通過super()方法調用父類的構造方法。也就是,在構造子類的同時,爲子類構造出跟父類相同的域。如此就在子類的對象中,也擁有了父類聲明的域了。
  在這裏插入圖片描述
  如果一個子類繼承了父類,那麼這個子類擁有父類所有的成員屬性和方法,即使是父類裏有private屬性的變量,子類也是繼承的,只不過不能使用,也就是說,它繼承了,但是沒有使用權,似乎又點矛盾,用我們通俗的說法就是 只能看,不能用,雖然是這樣,但是,我們還是可以通過set和get的方法來間接的訪問父類中的private屬性的變量。
  關於成員變量的繼承,父類的任何成員變量都是會被子類繼承下去的,這些繼承下來的私有成員雖對子類來說不可見,但子類仍然可以用父類的函數操作他們.

這樣的設計的意義就是我們可以用這個方法將我們的成員保護得更好,讓子類的設計者也只能通過父類指定的方法修改父類的私有成員,這樣將能把類保護得更好,這對一個完整的繼承體系是尤爲可貴的.


三、總結:

       總之,最後關於Java中子類能不能繼承父類的私有變量和方法?,只能這樣回答,以官方文檔解釋說明爲準,這裏我們明確一下“繼承”一詞的概念,在 Java 中,繼承一詞的意義是有限制的。一個子類只能繼承其父類的可訪問的成員,並且該子類沒有覆蓋或者說隱藏父類中的那些可訪問成員。所以,一個類的成員就是指在這個類中所聲明的屬性和方法,再加上從其父類繼承而來的屬性和方法。也就是說,子類是不能繼承父類的私有成員的。
       雖然子類不繼承父類中的私有成員,但是在父類中生命的這些私有成員仍然是子類類型對象的一部分。因爲在實例化對象的時候,只初始化在當前類中所聲明的屬性明顯是不足夠的,還需要初始化其父類中所有聲明的屬性。在實例化的過程中,JVM 需要爲對象的類及其父類中所有定義的屬性分配空間,包括父類中聲明的私有成員。
       所以,我們可以說:子類不能從父類繼承私有成員,但是子類的對象是包括子類所不能從父類中繼承的私有成員的。

其實我們不用糾結太多,懂得其中的原理,自己心裏清楚就行,當然對外解釋一切以官方爲準。

參考相關文章:
1.https://www.zhihu.com/question/51345942
2.https://blog.csdn.net/lhy_847csdn/article/details/80531706
3.http://www.blogjava.net/sitinspring/archive/2007/12/04/165288.html
4.https://zhidao.baidu.com/question/204223905962624885.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章