Java構造器(構造方法)詳解
什么是構造器
構造器通常也叫構造方法、建構式,構造器在每個專案中幾乎無處不在,當你new一個物件時,就會呼叫構造器,構造器格式如下:
[修飾符,比如public] 類名 (引數串列,可以沒有引數){ //這里不能有return}
文章目錄
- Java構造器(構造方法)詳解
- Java構造器
- 怎么定義構造器
- 構造器的使用
- 構造器的繼承
- 構造器、靜態代碼塊、構造代碼塊的執行順序,詳見下文實體
- 實體
- 1.默認構造器
- 2.禁止物件被外部創建
- 3.構造器多載
- 4.構造器的繼承
- 5. 構造器、靜態代碼塊、構造代碼塊的執行順序
- 5.1無繼承的情況
- 5.2有繼承的情況
Java構造器
構造器的注意事項:
- 構造器的名稱必須和類名一致
- 一個類中可以定義多個構造器,但是構造器的引數串列必須不同(多載)
- 如果我們沒有手動定義構造器,則Java系統會提供一個默認的構造器給我們使用,一旦我們定義了構造器,則系統會把默認的構造器識訓
- 構造器的作用:實體化物件,給物件賦初始值
- 代碼游離塊優先執行
怎么定義構造器
構造方法的名字必須和所在類的名字一致,沒有回傳值,但不能宣告void,訪問權限可以為任意,但是一般情況下使用public方法權限,構造方法中的引數可以根據需要自行定義,引數的不同的構造方法構成多載
public 構造方法名(引數){
...
}
/*注意:
1.構造方法沒有回傳值型別
2.構造方法名必須和該類的類名保持一致,大小寫都一樣
例:
class Fu
{
public Fu(){} //無參的公有構造方法
public Fu(int i){} //引數型別為int的公有構造方法
......
}
public class Demo extends Fu
{
public Demo(){} //無參的公有構造方法
public Demo(int i){} //引數型別為int的公有構造方法
public Demo(int i,double d){} //引數型別為int和double的公有構造方法
...
}
構造器的使用
Java中構造方法的使用有兩個地方,一個是跟在關鍵字new后面,類名加上一個小括號(),小括號內根據實際加上實參,另外一個是跟在關鍵字super或this后加上一個小括號(),小括號內根據實際添加實參,下面進行舉例,
例1:
Demo demo = new Demo(); //這里是呼叫的是一個無參的構造方法,必須宣告在方法中,最好宣告在主方法
上面構造方法的引數根據實際添加實參,Jvm根據構造方法的引數不同加載不同的構造方法
例2:
public Demo(){
this(2); //這里呼叫引數為int型別的本類的構造方法
}
例3:
public Demo(){
super(1); //呼叫引數為int型別的父類的構造方法
}
注意:例2和例3中this或super呼叫構造方法只能出現在構造方法中,而且必須出現在第一行,所以一個構造方法中第一行只能為this或super呼叫構造方法,兩者不能同時呼叫構造方法出現,而且注意this或super呼叫構造方法時,要留構造方法出口,意思就是最后呼叫的構造方法中沒有再呼叫別的構造方法!
構造器的繼承
子類構造器會默認呼叫父類無參構造器,如果父類沒有無參構造器,則必須在子類構造器的第一行通過 super關鍵字指定呼叫父類的哪個構造器,具體看下文例子,final類是不允許被繼承的,編譯器會報錯,很好理解,由于final修飾符指的是不允許被修改,而繼承中,子類是可以修改父類的,這里就產生沖突了,所以final類是不允許被繼承的,
構造器、靜態代碼塊、構造代碼塊的執行順序,詳見下文實體
- 無繼承的情況下的執行順序靜態代碼塊:只在程式啟動后執行一次,優先級最高構造代碼塊:任何一個構造器被呼叫的時候,都會先執行構造代碼塊,優先級低于靜態代碼塊構造器:優先級低于構造代碼塊總結一下優先級:靜態代碼塊 > 構造代碼塊 > 構造器
- 有繼承的情況下的執行順序:父類靜態代碼塊:只在程式啟動后執行一次,優先級最高 子類靜態代碼塊:只在程式啟動后執行一次,優先級低于父類靜態代碼塊 父類構造代碼塊:父類任何一個構造器被呼叫的時候,都會執行一次,優先級低于子類靜態代碼塊父類構造器:優先級低于父類構造代碼子類構造代碼塊:子類任何一個構造器被呼叫的時候,都會執行一次,優先級低于父類構造器子類構造器:優先級低于子類構造代碼塊總結一下優先級:父類靜態代碼塊 > 子類靜態代碼塊 > 父類構造代碼塊 > 父類構造器 > 子類構造代碼塊 > 子類構造器
實體
1.默認構造器
新建一個類,不提供任何構造器,編譯器會默認提供一個無參構造器,這就是為什么沒定義任何構造器,卻可以new 某個物件()
public class People {}
//以上這個People類就可以直接通過new People()來實體化
2.禁止物件被外部創建
如果不希望People在外部通過new People()來實體化,只需要將構造器定義為private
public class People{
private People(){
}
}
3.構造器多載
多載可以簡單理解為:同個方法名,不同的引數串列,如果希望People能在外部通過new People() 或 new People(“字串”) 來實體化,則通過以下代碼即可
public class People{
//通過new People()呼叫
public People(){
}
//通過new People("字串")呼叫
public People(String str){
}
}
4.構造器的繼承
定義父類構造器,由于該構造器自定義了一個帶參構造器,覆寫了默認的無參構造器,所以不能直接 new Father() 呼叫了,除非再定義一個無參構造器
//父類構造器
public class Father{
//自定義帶參構造器
public Father(String str){
System.out.println("父類的帶參構造方法,引數為:"+str);
}
}
定義子類構造器,繼承Father,由于Father沒有無參構造器,所以必須在子類構造器中通過 super(“字串”)來呼叫,否則編譯器會報錯
//子類構造器
public class Son extends Father{
//無參構造器
public Son(){
//由于Father()沒有無參構造器,所以必須在子型別構造器中通過super("字串")來呼叫,否則編譯器會報錯,
//如果沒定義這句,系統會默認呼叫super()
super("");
}
//帶參構造器
public Son(String str){
//由于Father()沒有無參構造器,所以必須在子型別構造器中通過super("字串")來呼叫,否則編譯器會報錯,
//如果沒定義這句,系統會默認呼叫super()
super(str);
}
}
5. 構造器、靜態代碼塊、構造代碼塊的執行順序
5.1無繼承的情況
public class Father {
static {
System.out.println("父類的靜態代碼塊,程式啟動后執行,只會執行一次");
}
//父類無參構造方法
public Father(){
System.out.println("父類的默認構造方法");
}
//多載,自定義父類帶參構造方法
public Father(String str){
System.out.println("父類的帶參構造方法,引數為:"+str);
}
{
System.out.println("父類構造代碼塊,每次呼叫構造方法都會執行的");
}
}
實體化Father
//實體化Father
public static void main(String[] args) {
System.out.println("---------------------------------------");
Father father1 = new Father();
System.out.println("---------------------------------------");
Father father2 = new Father("阿馬");
}
執行上述代碼
父類的靜態代碼塊,程式啟動后執行,只會執行一次
---------------------------------------
父類構造代碼塊,每次呼叫構造方法都會執行的
父類的默認構造方法
---------------------------------------
父類構造代碼塊,每次呼叫構造方法都會執行的
父類的帶參構造方法,引數為:阿馬
5.2有繼承的情況
定義父類Father
public class Father {
static {
System.out.println("父類的靜態代碼塊,程式啟動后執行,只會執行一次");
}
//父類無參構造方法
public Father(){
System.out.println("父類的默認構造方法");
}
//多載,自定義父類帶參構造方法
public Father(String str){
System.out.println("父類的帶參構造方法,引數為:"+str);
}
{
System.out.println("父類構造代碼塊,每次呼叫構造方法都會執行的");
}
}
定義子類Son,繼承自父類Father
//子類構造器
public class Son extends Father{
static {
System.out.println("子類的靜態代碼塊,程式啟動后執行,只會執行一次,先執行父類的,在執行子類的");
}
{
System.out.println("子類構造代碼塊,每次呼叫構造方法都會執行的");
}
//無參構造器
public Son(){
//這里沒有指定呼叫父類的哪個構造方法,會默認呼叫super(),呼叫父類的無參構造器public Father()
}
//多載構造器,多傳兩個引數
public Son(String str1,String str2){
//必須寫在構造器第一行,呼叫父類的帶參構造器public Father(str)
super(str1);
System.out.println("子類帶參構造器:"+str2);
}
}
實體化Son
public static void main(String[] args) {
System.out.println("-----------------------------------");
Son son1 = new Son();
System.out.println("-----------------------------------");
Son son2 = new Son("子類第一個引數","子類第二個引數");
}
執行上述代碼
父類的靜態代碼塊,程式啟動后執行,只會執行一次
子類的靜態代碼塊,程式啟動后執行,只會執行一次,先執行父類的,在執行子類的
-----------------------------------
父類構造代碼塊,每次呼叫構造方法都會執行的
父類的默認構造方法
子類構造代碼塊,每次呼叫構造方法都會執行的
-----------------------------------
父類構造代碼塊,每次呼叫構造方法都會執行的
父類的帶參構造方法,引數為:子類第一個引數
子類構造代碼塊,每次呼叫構造方法都會執行的
子類帶參構造器:子類第二個引數
數");
}
執行上述代碼
```java
父類的靜態代碼塊,程式啟動后執行,只會執行一次
子類的靜態代碼塊,程式啟動后執行,只會執行一次,先執行父類的,在執行子類的
-----------------------------------
父類構造代碼塊,每次呼叫構造方法都會執行的
父類的默認構造方法
子類構造代碼塊,每次呼叫構造方法都會執行的
-----------------------------------
父類構造代碼塊,每次呼叫構造方法都會執行的
父類的帶參構造方法,引數為:子類第一個引數
子類構造代碼塊,每次呼叫構造方法都會執行的
子類帶參構造器:子類第二個引數
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/299434.html
標籤:其他
