第十七、Java面向對象之構造函數與構造代碼塊

 我們人出生的時候,有些人一出生之後再起名字的,但是有些人一旦出生就已經起好名字的。那麼我們在java裏面怎麼在對象一旦創建就賦值呢?

需求: 使用java類描述 一個嬰兒, 一種嬰兒一出生就具備了名字(白戶),還有一種嬰兒就是 出生之後纔有名字 的(黑戶)。

構造函數的作用: 給對應的對象進行初始化。

構造函數的定義的格式:

修飾符  函數名(形式參數){
函數體...
}

構造函數要注意的細節:

1. 構造函數 是沒有返回值類型的。
2. 構造函數的函數名必須要與類名一致。
3. 構造函數並不是由我們手動調用的,而是在創建對應的對象時,jvm就會主動調用到對應的構造函數。
4. 如果一個類沒有顯式的寫上一個構造方法時,那麼java編譯器會爲該類添加一個無參的構造函數的。
5. 如果一個類已經顯式的寫上一個構造方法時,那麼java編譯器則 不會再爲該類添加 一個無參 的構造方法。
6. 構造函數是 可以在一個類中以函數重載 的形式存在多個 的。

/*
描述一個員工類,員工具備 的屬性:id\ name \ age 。
具備的公共行爲: 工作。 

要求:一旦創建一個員工對象 的時候,那麼該員工對象就要對應 的屬性值。

*/

class Employee{
	
	int id;  //編號
	String name;  //名字
	int age; //年齡

	//構造函數
	public Employee(int a, String b , int c){
		id =a;
		name = b;
		age = c;
	}

	public void work(){
		System.out.println(name+"好好工作,努力掙錢!!");
	}
}


class MyClass 
{
	public static void main(String[] args) 
	{
		//創建一個員工對象
		Employee e = new  Employee(110,"米奇",20);
		System.out.println("編號:"+ e.id+" 名字:"+e.name +" 年齡:"+ e.age);
	}
}


疑問:創建對象時,jvm就會調用到對應的構造方法,那麼我們以前沒有學構造方法,那麼以前創建對象時,jvm是否 也會調用構造方法呢?如果有?構造方法從何而來呢?

會調用, java編譯器在編譯的 時候給加上去的。

jdk提供了一個java開發工具(javap.exe)給我們進行反編譯的。


javap 反編譯工具的使用格式javap -c -l -private 類名


疑問: java編譯器添加 的無參構造方法的權限修飾符是 什麼?
與類的權限修飾是一致的。



構造函數與普通 函數的區別:

1. 返回值類型的區別:
1. 構造函數是沒有返回值類型的。
2. 普通函數是有返回值類型的,即使函數沒有返回值,返回值類型也要寫上void。
2. 函數名的區別:
1. 構造函數的函數名必須要與類名一致。
2. 普通函數的函數名只要符合標識符的命名規則即可。
3. 調用方式的區別:
1. 構造函數是 在創建對象的時候由jvm調用的。
2. 普通函數是由我們使用對象調用的,一個對象可以對象多次普通 的函數,
4. 作用上的區別:
1. 構造函數 的作用用於初始化一個對象。
2. 普通函數是用於描述一類事物的公共行爲的。



//嬰兒類
class Baby{
	
	int id; //身份證
	String  name;  //名字

	//構造函數
	public  Baby(int i , String n){
		id  = i;
		name = n;
		System.out.println("baby的屬性初始化完畢!!");
	}

	//無參 的構造函數
	public Baby(){
		System.out.println("無參的構造函數被調用了..");
	}

	
	//哭
	public void cry(){
		System.out.println(name+"哇哇哭...");
	}	
}


class MyClass 
{
	public static void main(String[] args) 
	{	
		//創建一個baby對象
		Baby b1 = 	new Baby(110,"狗娃"); //嬰兒誕生   白戶
		System.out.println("編號:"+ b1.id +" 姓名:"+ b1.name);
		b1.cry();
		b1.cry();

	

		/*
		//黑戶
		Baby b2 = new Baby();
		new Baby();

		b2.id = 112;
		b2.name = "狗剩";
		System.out.println("編號:"+ b2.id +" 姓名:"+ b2.name);
		*/
	}
}


問題:要求每個小孩出生都會哭,這份代碼有兩個構造函數,如果需要每個小孩出生都要哭的話,那麼就需要在不同的構造函數中都調用cry()函數,但是這樣子的話造成了代碼重複問題,那麼怎麼解決呢?構造代碼塊


構造代碼塊


構造函數的作用: 給對應的對象進行初始化。

構造代碼塊的作用:給對象進行統一的初始化。

1:給對象進行初始化。對象一建立就運行並且優先於構造函數。

2:與構造函數區別

      1)  構造代碼塊和構造函數的區別,構造代碼塊是給所有對象進行統一初始化, 構造函數給對應的對象初始化。

      2)  構造代碼塊的作用:它的作用就是將所有構造方法中公共的信息進行抽取。

           例如孩子一出生統一哭


構造代碼塊的格式:

{
構造代碼塊
}


注意: 構造代碼塊的大括號必須位於成員 位置上。


代碼塊的類別:
1. 構造代碼塊。
2. 局部代碼塊.   大括號位於方法之內。  作用:縮短局部 變量 的生命週期,節省一點點內存。
3. 靜態代碼塊  static 


class Baby{
	
	int id; //身份證
	String  name;  //名字
	
	//構造代碼塊...
	{
		//System.out.println("構造代碼塊的代碼執行了......");
		
	}

	//帶參構造函數
	public  Baby(int i , String n){
		id  = i;
		name = n;
	}
	
	//無參構造方法
	public Baby(){
	}

	public void cry(){
		System.out.println(name+"哇哇哭...");
	}	
}



class MyClass 
{
	public static void main(String[] args) 
	{
		Baby b1 = new Baby(110,"米奇"); 
		System.out.println("編號:"+ b1.id + " 名字:"+b1.name);
		/*
		System.out.println("編號:"+ b1.id + " 名字:"+b1.name);
	
		new Baby(112,"唐老鴨");
		new Baby();
		*/
		/*
		new Baby(110,"米奇");
		new Baby(112,"唐老鴨");
		new Baby();
		*/
	}
}


構造代碼塊要注意的事項:

1. java編譯器編譯一個java源文件的時候,會把成員變量的聲明語句提前至一個類的最前端。
2. 成員變量的初始化工作其實都在在構造函數中執行的。
3. 一旦經過java編譯器編譯後,那麼構造代碼塊的代碼塊就會被移動構造函數中執行,是在構造函數之前執行的,構造函數的中代碼是最後執行 的。
4. 成員變量的顯示初始化與構造代碼塊 的代碼是按照當前代碼的順序執行的。


class MyClass 
{
	//構造函數
	public MyClass(){   //構造函數
		i = 300000000;	
	}
		
	//構造代碼塊   //構造代碼塊的初始化
	{
		i = 200000000;
	}
	
	int i = 100000000;	 //成員變量的顯初始化	

	public static void main(String[] args) 
	{
		MyClass d = new MyClass();
		System.out.println("i = "+d.i); 
	}
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章