我們都知道Java中的繼承是復用代碼、擴展子類的一種方式,繼承使得Java中重覆的代碼能夠被提取出來供子類共用,對於Java程式的性能以及修改和擴展有很大的意義,所以這是一個非常重要的知識點。 那麼對於繼承的知識點,你真的都瞭解了嗎? 首先,我們都知道子類繼承父類,就能直接訪問父類的公共屬性以及受保 ...
我們都知道Java中的繼承是復用代碼、擴展子類的一種方式,繼承使得Java中重覆的代碼能夠被提取出來供子類共用,對於Java程式的性能以及修改和擴展有很大的意義,所以這是一個非常重要的知識點。
那麼對於繼承的知識點,你真的都瞭解了嗎?
首先,我們都知道子類繼承父類,就能直接訪問父類的公共屬性以及受保護屬性(public和protected),同時也能直接訪問父類的公共方法以及受保護方法;其次,對於父類的私有屬性,子類並不能直接訪問,但是可以通過父類提供的getter和setter方法進行訪問,而父類的私有方法,子類無法直接訪問;還有,對於父類的包訪問許可權屬性和方法(default),如果子類和父類在同一個包下,子類可以繼承並且直接訪問到,如果二者不在同一個包下,則子類無法直接訪問到這些方法和屬性,但是同樣的可以通過父類的getter和setter方法去訪問這些屬性;最後一點,我們很多人其實都有疑問,子類繼承父類,不是應該繼承了父類的所有東西嗎,為什麼訪問不到那些私有屬性?其實這裡要從記憶體分析來看,當我們要創建一個子類的對象時,Java虛擬機會先幫我們生成對應的父類對象,因為我們都知道,在子類的構造方法中中,首行代碼必須是父類構造方法的調用,即通過super關鍵字來調用,如果不寫,則虛擬機會自動幫我們加入super()(前提是父類有無參構造方法),如果父類沒有無參構造方法而有有參構造方法,那麼子類的構造方法必須顯性的調用父類的構造方法,否則會報錯。通過這一點我們就知道在創建子類對象的時候,Java虛擬機是先創建父類的對象,然後在這個父類對象的基礎上加上子類特有的方法和屬性,從而創建出子類對象,因此從這裡我們可以得知,子類是擁有父類的所有屬性和方法的,但是擁有不代表能夠訪問!!!父類私有的方法和對象是子類無法直接訪問的,子類僅僅是擁有但訪問不到!
這裡補充一下特殊的情況,就是父類中的final屬性和方法以及static屬性和方法子類是能夠繼承並直接訪問的,但是final的屬性子類無法修改,final的方法子類無法重寫,說明final修飾的方法並不具備動態綁定;而static的屬性和方法會存在隱藏現象,即當子類中出現與父類static變數或者方法同名的變數或者方法時,子類的成員變數和靜態方法會被隱藏,如:父類中有public static int nun = 1,而子類中有public static int num = 2,這時候用向上轉型的對象(比如Father father = new Son(),其中Father是父類,Son是子類)去輸出num屬性會發現輸出為1!static方法的隱藏理論同屬性一致。如果你想調用子類的static方法和屬性,你需要定義明確子類(如Son son = new Son())的對象去調用,從這裡看出static方法和屬性也不支持動態綁定!所以子類並不能重寫父類的static方法。
以上是我個人對Java繼承一些見解,如果有補充或者修改的地方請在評論區指出來,謝謝!
知識點擴展:Java中的動態綁定,是實現多態的本質,它只針對普通方法,而且僅僅是方法,不包括成員變數那些!所以說如果你用一個向上轉型的父類對象去調用父類對象中的非final、非static屬性,即使它對應的子類中有一樣的屬性,最終輸出還是父類對象的屬性!最後補充一點,Java中除了final、static、private修飾的方法以及構造器(構造器預設為static)為靜態綁定之外,其他方法皆為動態綁定。