类的加载次序与继承
原創(chuàng)轉(zhuǎn)載請注明出處:http://www.cnblogs.com/chaeyeon/p/6146169.html
如果:A extends B
1.若要加載類A,應先加載父類B。而只要加載一個類,靜態(tài)字段就會分配內(nèi)存,靜態(tài)代碼塊就會執(zhí)行。則先為父類B(Object)的靜態(tài)變量分配內(nèi)存以及執(zhí)行父類的靜態(tài)語句塊(執(zhí)行先后順序按由書寫執(zhí)行決定)。
2.然后再加載子類A,及為類A的靜態(tài)變量分配內(nèi)存以及執(zhí)行類A的靜態(tài)語句塊。(并且1、2步驟只會在類第一次加載的時候執(zhí)行,即最多執(zhí)行一次)
結(jié)論一:子類的加載,必須先加載其父類,類的加載伴隨著,靜態(tài)變量的內(nèi)存分配,靜態(tài)語句的執(zhí)行。
可以通過:Class.forname(A)加載類A。在父類的靜態(tài)代碼中輸出父類中的靜態(tài)變量,并在子類的靜態(tài)代碼塊中輸出子類的靜態(tài)字段來驗證1,2結(jié)論。
3.若需實例化類A,則在子類的構(gòu)造方法執(zhí)行之前,先調(diào)用其父類B的構(gòu)造函數(shù)。并且在調(diào)用其父類B的構(gòu)造函數(shù)前、在父類中會發(fā)生:
????????1.父類B中的非靜態(tài)變量分配內(nèi)存以及執(zhí)行父類中的非靜態(tài)語句塊.再調(diào)用父類B中的構(gòu)造函數(shù)初始化初始化父類中的字段(因為父類中的字段要被子類繼承,而字段的初始化,要通過自己的構(gòu)造函數(shù)完成)。
2.然后再給類A中的非靜態(tài)變量分配內(nèi)存以及執(zhí)行類A非靜態(tài)語句塊.最后調(diào)用A中的構(gòu)造函數(shù)初始化。( 并且第次實例化子類對象的時候過程3都會發(fā)生)
結(jié)論二:實例化對象的時候需要調(diào)用構(gòu)造方法,由于子類繼承父類的成員變量,所以實例化子類的時候,在子類的構(gòu)造方法中一定要先調(diào)用了父類的構(gòu)造方法(super()在子類的構(gòu)造方法的第一行)來給子類中繼承自父類的字段初始化,然后再執(zhí)行子類中的構(gòu)造函數(shù)來初始化子類特有的字段,這個步驟,會在每次實例化子類對象的時候重復執(zhí)行。注意:一個類構(gòu)造方法每次被調(diào)用之前,一定會先執(zhí)行一次該類中的實例語句塊。
5.對于靜態(tài)方法和非靜態(tài)方法都是被動調(diào)用,即系統(tǒng)不會自動調(diào)用執(zhí)行,所以用戶沒有調(diào)用時都不執(zhí)行,方法都存放在方法區(qū)中(靜態(tài)區(qū))等待用戶的調(diào)用。只有用戶調(diào)用時才給方法中的局部變量分配內(nèi)存。
注意:加載不意味著執(zhí)行!!!
總結(jié):
子類的加載必先加載父類。類的加載伴隨著靜態(tài)變量的分配與靜態(tài)語句塊的執(zhí)行(這個過程只會類第一次被加載時執(zhí)行 )
子類的實例化,伴隨著父類的實例化(先實例化父類,然后實例化子類),此時伴隨著成員變量和實例語句塊的執(zhí)行(這個過程在每次實例化子類的時候都會發(fā)生)
繼承:
1.子類會繼承父類中所有的字段和方法(包括私有的字段和方法),但構(gòu)造方法不能被繼承。
2.子類即使繼承了父類的私有字段,也不能直接訪問,只能間接訪問,或不能訪問(但是可以通過父類提供的公開的方法中來做到間接地訪問父類中私有的成員字段或方法,既然能被訪問,說明子類為父類的私有字段分配了空間,繼承了父類的私有字段,不然數(shù)據(jù)往那里存)
通過.net的調(diào)試器,可以清楚的驗證這一結(jié)論,既然子類中可以訪問父類的成員方法的成員變量那么可以理解為在子類對象中包含一個父類對象。
3.構(gòu)造方法雖然不能被繼承,但是子類中的任何一個構(gòu)造方法執(zhí)行前都會執(zhí)行父類的構(gòu)造方法。目的同繼承為了減少代碼的重復因為可以通過在子類中調(diào)用父類的構(gòu)造來初始化子類,而不用在子類中在寫一遍對父類中成員變量賦值的代碼(如果子類中不顯示地調(diào)用默認調(diào)用父類的無參構(gòu)造,可以在父類中的無參構(gòu)造中輸出一名話,然后在實現(xiàn)化一個子類來驗證)
4.子類可以通過方法的重寫,或字段的重名來覆蓋都父類中的方法或都字段。但是只要該字段或方法在父類中不是私有的,在子類中仍然可以通過”super.“字段名或方法名去訪問。
5.this表示的就是當前對象,誰調(diào)用就指代誰,this就是對象的引象,保證對象的地址,每一個對象都有this存在堆中,可以理解為Object o=new Object();new返回的就是堆中對象中的this(this保存對象的引用,它的含義等價引用)靜態(tài)代碼段中沒有this
6、super(或者base)都是指代當前子類對象中的父類型的特征。super指代子類從父類中繼承過來的字段或方法,用于區(qū)分子類中重寫父類的方法或者子類覆蓋父類的中的字段,就可以通過”super.“方法名或字段名來顯示的在子類中調(diào)用父類中的方法或字段,即使這些方法或字段被子類重寫或覆蓋。super不是引用,不保存內(nèi)存地址,它只是存在于this中來指代子類從父類繼承過來的數(shù)據(jù)(即父類中的數(shù)據(jù)),和子類中特有的數(shù)據(jù)。this能存在的地方super就存在,super是this的組成部分。
驗證:
? 從這張圖看所謂的繼承應該很明了
?
轉(zhuǎn)載于:https://www.cnblogs.com/chaeyeon/p/6146169.html
總結(jié)
- 上一篇: 嵌入式Linux驱动学习之路(十五)按键
- 下一篇: 图书管理模块功能设计