JAVA入門—寫給大忙人看的構造函數

類的構造函數

構造函數在每個類中都存在,是面向對象設計語言(OOP)的特色。

特點:

  • 函數名與類名是相同的
  • 不能有返回值
  • 可以有參數,也可以沒有參數
  • 可以有多個

說明:

  • 聲明一個對象,系統首先爲該對象分配內存,然後立即自動調用該對象的構造函數

注意:

  • 任何一個類對象被生成時候一定會調用該類的構造函數
  • 無論一個類有多少個構造函數,生成一個類對象時一定只會調用其中的某一個構造函數!
class A
{
	int i;
	int j;
}

class TestMemo
{
	public static void main(String[] args)
	{
		A aa = new A();
							//運行此語句時,
							//首先
							//->(A *)malloc(sizeof(A));
							//->new A();在堆中動態分配一塊區域,被當作了A對象
							//->aa本身的內存是在棧中分配的
							//其次
							//調用系統默認分配的class A()這個無形參的構造函數
							
							//堆中內存的地址賦給了aa
							//aa指向堆中的內存,aa代表了堆中的內存
							//aa.i代表:aa這個靜態指針變量所指向的動態內存中的A對象數據成員i
							
							//
		aa.i = 10;
		aa.j = 20;
		System.out.printf("%d, %d\n",aa.i,aa.j);
	}
}

_________________________
程序運行示例:
10, 20
_________________________

這個程序表面上沒有構造函數(實際上你懂的),但是程序可以正常運行。這是因爲若沒有人爲的創建的構造函數,系統會自動爲該程序創建無參構造函數

一旦人爲的創建構造函數,系統就不再會自動爲該程序創建無參構造函數

class A
{
	int i;
	int j;

		public A(int a,int b) 
    {											//此處認爲創建有參數的構造函數,系統就不再會爲程序自動創建無參構造函數

        System.out.printf("有參構造函數被調用了!");
    }
}


class TestMemo
{
	public static void main(String[] args)
	{
		A aa = new A();//(A *)malloc(sizeof(A));
							//new A();在堆中動態分配一塊區域,被當作了A對象
							//aa本身的內存是在棧中分配的
							//堆中內存的地址賦給了aa
							//aa指向堆中的內存,aa代表了堆中的內存
							//aa.i代表:aa這個靜態指針變量所指向的動態內存中的A對象數據成員i
		aa.i = 10;
		aa.j = 20;
		System.out.printf("%d, %d\n",aa.i,aa.j);
	}
}

程序運行示例:
————————————————————————————————————
TestMemo.java:18: 錯誤: 無法將類 A中的構造器 A應用到給定類型;
                A aa = new A();//(A *)malloc(sizeof(A));
                       ^
  需要: int,int
  找到:    沒有參數
  原因: 實際參數列表和形式參數列表長度不同
1 個錯誤
————————————————————————————————————

該程序就充分表現了一旦人爲創建構造函數,系統就不再創建,可以理解系統是一個特立獨行的人,別人幹過的事情,它絕不會再幹。

class A
{
    private int i;
    private int j;
    /**

    public B(int a,int b)      /*error	函數名與類名必須是相同的*/
    public void A(int a,int b)    /*error ,構造函數不能有返回值,這是類A的一個普通的操作,不再是構造函數*/

     */
    public A()
    {
    	System.out.printf("一個類的構造函數可以有多個\n");
    }
    public A(int a,int b) 
    {
        i = a;
        j = b;
        System.out.printf("有參構造函數被調用了!\n");
    }

    public void show()
    {
        System.out.printf("i = %d,j = %d\n",i,j);
    }
}
class Main
{
    public static void main(String[] args)
    {
        A aa = new A(1,2);	//此處創建對象aa的同時,系統還會調用有參的構造函數public A(int a,int b) 
        A bb = new A();		//此處創建對象bb的同時,系統還會調用無參的構造函數 public A()
        
        aa.show();
    }
}
程序運行示例:
————————————————————————————————————
有參構造函數被調用了!
一個類的構造函數可以有多個
i = 1,j = 2
————————————————————————————————————

構造函數,只有構造此類對象的時候會調用!

幾點要求:

​ 1、此構造函數沒有返回值,故嚴格上講,不能稱之爲函數,void也不能加

​ 2、一個類的構造函數可以有很多個,在類創建對象時候,根據A aa = new A( );中的

​ 括號中形式參數的個數來匹配相應的構造函數

擴展補充

構造函數的返回值問題

  • 在一個類中可以定義多個函數名與類名相同卻有返回值的函數,函數爲void或者int或者double都是可以的,

    這些有返回值的函數只要能滿足重載特點,就可以同時存在一個類中,不過要注意:這些有返回值的函數(包括返回值爲void的函數)都不是構造函數,都不會像創建對象的同時調用構造函數那樣被類對象自動調用。

  • 當然也可以定義多個沒有返回值的函數,注意連void都不可以加,這些函數纔是構造函數,無返回值的函數纔會被對象自動調用。

  • 如果定義了有返回值並且方法名與類名相同的方法(類中的操作),程序並不會報錯,但是容易產生歧義,所以強烈建議不要在構造函數的前面加返回值

構造函數數據成員的賦值問題

  • 如果在定義的同時沒有初始化,則它的值時系統自動分配好的默認值!

  • 如果在定義數據成員的同時賦初值,則是可以的,也就是說該值是生效的,注意在C++中則不可以,在C++中一個類的數據成員不能在定義的同時初始化,它只能在構造函數中初始化

  • 如果在定義數據成員的同時賦初值,當然生效,但如果在構造函數中又改變了定義時賦的初值,則該數據成員最終的值就是構造函數中修改之後的那個值,因爲:系統先執行定義時賦的初值,然後再執行構造函數中賦的初值

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