引入多型後構造器的呼叫順序:基類的構造器總是在匯出類的構造過程中被呼叫,而且按照繼承層次逐漸向上鏈結,以使每個基類的構造器都能得到呼叫。這樣做是有意義的,因為構造器具有一項特殊任務:檢查物件是否被正確的構造。匯出類只能訪問它自己的成員,不能訪問基類中的成員(基類成員通常是private型別)。
只有基類的構造器才具有恰當的知識和許可權來對自己的元素進行初始化。因此,必須令所有構造器都得到呼叫,否則就不可能正確構造完整物件。
這正是編譯器為什麼要強制每個匯出類部分都必須呼叫構造器的原因。在匯出類的構造器主體中,如果沒有明確指定呼叫某個基類構造器,它就會「默默」地呼叫預設構造器。如果不存在預設構造器,編譯器就會報錯(若某個類沒有構造器,編譯器會自動合出乙個預設構造器)。
讓我們來看下面這個例子,它展示組合、繼承以及多型在構建順序上的作用:
package com.mufeng.theeighthchapter;
class meal
}class bread
}class cheese
}class lettuce
}class lunch extends meal
}class portablelunch extends lunch
}public class sandwich extends portablelunch
public static void main(string args)
}meal()
lunch()
portablelunch()
bread()
cheese()
lettuce()
sandwich()在這個例子中,用其它類建立了乙個複雜的類,而且每個類都有乙個宣告它自己的構造器。其中最重要的類是sandwich,它反映了三層繼承(若將自object的隱含繼承也算在內,就是四層)以及三個成員物件。
當在main()裡建立乙個sandwich物件後,就可以看到輸出結果。這也表明了這一複雜物件呼叫構造器要遵照下面的順序:呼叫基類構造器。這個步驟會不斷地反覆遞迴下去,首先是構造這種層次結構的根,然後是下一層匯出類,等等,直到最底層的匯出類。按宣告順序呼叫成員的初始化方法。呼叫匯出類構造器的主體。
構造器的呼叫順序是很重要的。當進行繼承時,我們已經知道基類的一切,並且可以訪問基類中任何宣告為public和protected的成員。這意味著在匯出類中,必須假定基類的所有成員都是有效的。一種標準方法是,構造動作一經發生,那麼物件所有部分的全體成員都會得到構建。
然而,在構造器內部,我們必須確保所要使用的成員都已經構建完畢。為確保這一目的,唯一的辦法就是首先呼叫基類的構造器。
那麼在進入匯出類構造器時,在基類中可供我們訪問的成員都已得到初始化。此外,知道構造器中的所有成員都有效也是因為,當成員物件在類內進行定義的時候(比如上例的b、c和l),只要可能,就應該對它們進行初始化(也就是說,通過組合方法將物件置於類內)。若遵循這一規則,那麼就能保證所有基類成員以及當前物件的成員物件都被初始化了。但遺憾的是,這種做法並不適用於所有情況,這一點我們會在下一節中看到。
構造器呼叫順序
構造器呼叫順序 1 基類建構函式 2 申明順序的成員初始化方法 3 匯出類構造器。class bread class sandwich class cheese class supermeal extends bread class meal extends supermeal public sta...
建構函式(構造器)的呼叫順序
package demo2 class meal class bread class cheese class lettue class lunch extends meal class portablelunch extends lunch public class demo1 extends p...
java構造器的呼叫順序
基類的構造器總是在匯出類的構造過程中被呼叫,而且 按照繼承層次逐漸向上鏈結,以使每個基類的構造器都能得到呼叫.這樣做是有意義的,因為構造器有一項特殊的任務 檢查物件是否被正確的構造.匯出類只能訪問它自己的成員,不能訪問基類的成員 基類成員通常是private型別的 只有基類的構造器才具有恰當的知識和...