3 回答

TA貢獻2051條經驗 獲得超10個贊
對象構建的順序是:
變量聲明和初始化
實例構造函數塊
constructor
如果一個類有父類,則在實際類之前先為父類完成相同的順序。
父母第一
整數 = 9
首先評估,num
設置為 9(父母的 1)
父構造函數代碼...9
實例初始化塊在構造函數(父類的 2.)之前執行
父構造函數運行
構造函數被調用(parent's 3.)
兒童節目...0
Parent
調用的構造函數show()
。show()
被覆蓋,因此Child
調用了。
孩子的 1. 和 2. 還沒有被調用,因此 overriding num
inChild
仍然是 0。*1
然后孩子
整數 = 8
Child
1. 被評估
子構造函數代碼...8
Child
的 2.num
在此之后設置為 10。
子構造函數運行
Child
的 3。
兒童節目...10
Child
的構造函數調用show()
。
*1:
這就是為什么final
在構造函數中調用非方法是非常危險的。方法往往依賴于被初始化的成員變量;他們不是在這一點上。
NullPointerException
如果這是一個非原始變量,如果您的方法試圖訪問它,您很可能會遇到 a 。

TA貢獻1852條經驗 獲得超1個贊
當 java 創建一個子類時,它必須調用super()
初始化父類——這樣它就可以在超類或其他活動中實例化私有字段。(這不會創建父類的對象。)這就是您看到的原因Parent constructor code...9
- 它正在調用父代碼,并打印父類的num
.
因為您創建了一個子類,所以在父構造函數中show()
調用了子類。這就是為什么在構造函數中調用非 final 方法是危險的——如果子對象覆蓋了它們,則將調用子對象的方法。
孩子的num
是 0 因為Java 將成員變量初始化為默認值,而您的代碼還沒有機會將其設置為 10。
至于你的子代碼,它num
沒有被覆蓋,它被隱藏了——只有方法可以被覆蓋。這就是為什么您的孩子show()
在正確初始化后將其顯示為 10 的原因。如果你想訪問父變量,你可以用 來實現super.num
,但這通常被認為是不好的做法,因為它會引起混淆。
添加回答
舉報