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++中一个类的数据成员不能在定义的同时初始化,它只能在构造函数中初始化

  • 如果在定义数据成员的同时赋初值,当然生效,但如果在构造函数中又改变了定义时赋的初值,则该数据成员最终的值就是构造函数中修改之后的那个值,因为:系统先执行定义时赋的初值,然后再执行构造函数中赋的初值

猜你喜欢

转载自blog.csdn.net/qq_43656353/article/details/104851586