类的构造函数

 

  • 类的构造函数特点:

        1. 构造函数也称为构造方法,构造函数名和类名相同。

     2. 构造函数不能有返回值,也不能用void声明。

   3. 构造函数可以有参数,也可以无参数,在一个类中,可以定义多个构造函数。

    4. 构造函数主要是对类进行初始化,在new的时候调用。

    5. 任何一个类对象被生成时一定会调用该类的构造函数。

    6. 无论一个类中定义了多少个构造函数,在生成类对象时一定只会调用其中的某一个构造函数。

    7. 所有的类都有构造函数,在定义一个类时,如果你不定义构造函数,则系统默认生成一个空的构造函数,如果你自己定义了构造函数,则系统默认的构造函数就失效。

    8. 创建类对象语句:A aa = new A(); 其实new后面的A()就是构造函数。

 


  • 构造函数的返回值问题:

1. 在一个类中,可以定义多个函数名和类名相同但有返回值的函数,返回值可以为void或int或String或double等任意类型,这些有返回值的函数只要能满足重载特点,就可以同时存在一个类中,不过这些有返回值的函数(包括返回值为void的函数)都不是构造函数,在生成类对象时都不会被调用。

   2. 如果定义了有返回值并且函数名和类名相同的函数,程序并不会报错,而且这种函数也可以和普通函数一样被调用,但是容易产生歧义,最好不要定义这种函数。


1 /**
 2     @author   zst
 3     @version  1.0
 4     
 5 */
 6 public class A{
 7     /*
 8         下面三个函数的函数名都和类名相同,但都不是构造函数
 9         三个函数都满足重载的特点,所以可以同时存在同一个类中
10     */
11     
12     //不是构造函数,
13     public void A(){
14         System.out.println("调用了返回值为void,函数名为A的函数");
15     }
16     
17     //不是构造函数
18     public int A(int i){
19         System.out.println("调用了返回值为int,函数名为A的函数");
20         return i;
21     }
22     
23     //不是构造函数
24     public String A(String s){
25         System.out.println("调用了返回值为String,函数名为A的函数");
26         return s;
27     }
28     
29 }
1 /**
 2     @author   zst
 3     @version  1.0
 4     
 5 */
 6 public class ConstructorTest{
 7     public static void main(String[] args){
 8         
 9         A aa = new A(); //这里调用的构造方法是系统默认的为空的构造方法
10         
11         aa.A();
12         aa.A(0);
13         aa.A("hello");
14         
15     }
16     
17 }
18 /*
19     输出:
20         调用了返回值为void,函数名为A的函数
21         调用了返回值为int,函数名为A的函数
22         调用了返回值为String,函数名为A的函数
23 */

  • 构造函数调用

    当类中定义了多个构造函数,创建类对象时,只能指定调用某一个构造函数。

1 /**
 2     @author   zst
 3     @version  1.0
 4     
 5 */
 6 public class A{
 7     public A(){
 8         System.out.println("调用了无参构造函数创建对象");
 9         
10     }
11     
12     public A(int i)
13     {
14         System.out.println("调用了一个参数的构造函数创建对象");
15         
16     }
17     
18     public A(int i,int j)
19     {
20         System.out.println("调用了两个参数的构造函数创建对象");
21     }
22     
23     
24 }
25 /**
26     @author   zst
27     @version  1.0
28     
29 */
30 public class ConstructorTest02{
31     public static void main(String[] args){
32         
33         A aa1 = new A(); 
34         
35         A aa2 = new A(0);
36         
37         A aa3 = new A(1,2);
38         
39     }
40     
41 }
42 /*
43     输出:
44         调用了无参构造函数创建对象
45         调用了一个参数的构造函数创建对象
46         调用了两个参数的构造函数创建对象
47 */

  • 在创建对象时,数据成员的初始化赋值问题

  1. 如果数据成员在定义时不初始化,当一个对象被创建时,数据成员会被系统默认赋给一个默认值。各种类型的数据成员初始化默认值如下:

数据成员类型

默认初始化

byte

0

short

0

int

0

long

0L

float

0.0F

double

0.0D

char

'\u0000' (表示为空)

boolean

false

引用类型

null

 

    2. 如果数据成员在定义的同时赋初始值,则这个初始值是有效的,但如果在构造函数中又改变了定义时赋的初值,则该数据成员最终的值就是构造函数中修改之后的那个值,这是因为当调用构造函数创建对象时,会先给数据成员进行初始化,如果数据成员在定义时赋了值,则此时数据成员的初值为定义时赋给它的值,然后接着执行构造函数里的赋值语句,重新修改数据成员的初始化值。


1 /**
 2     @author   zst
 3     @version  1.0
 4     
 5 */
 6 public class A{
 7   //没有初始化的数据成员
 8   private int i;
 9   private String s;
10   private double d;
11   
12   //初始化的数据成员
13   private float f = 11.1f;
14   private boolean b = false;
15   
16   
17   //无参构造函数
18   public A(){
19   
20   }
21   
22   
23   public void f(){
24   
25     System.out.println("没有初始化的数据成员,系统赋予默认值");
26     System.out.println(i);
27     System.out.println(s);
28     System.out.println(d);
29     
30   }
31   
32   public void g(){
33     System.out.println("初始化的数据成员,初始化的值是有效的");
34     System.out.println(f);
35     System.out.println(b);
36     
37   }
38   
39   //有参构造函数,修改初始化时的值,数据成员最终的值是修改后的值
40   public A(float f,boolean b)
41   {
42         f = f;
43         b = b;
44         
45         System.out.println("在构造函数中修改数据成员的初始化值,数据成员最终的值为修改后的值");
46         System.out.println(f);
47         System.out.println(b);
48   }
49   
50   
51     
52 }
53 /**
54     @author   zst
55     @version  1.0
56     
57 */
58 public class ConstructorTest03{
59     public static void main(String[] args){
60         
61         A aa1 = new A(); 
62         aa1.f();
63         aa1.g();
64         
65         A aa2 = new A(99.9f,true);
66         
67         
68     }
69     
70     
71 }
72 /*
73     输出:
74         没有初始化的数据成员,系统赋予默认值
75         0
76         null
77         0.0
78         初始化的数据成员,初始化的值是有效的
79         11.1
80         false
81         在构造函数中修改数据成员的初始化值,数据成员最终的值为修改后的值
82         99.9
83         true
84 */

  3. 需要注意的一点:对于一个类的数据成员,如果定义时不初始化,则创建对象时,系统就会自动赋给默认的初始值,但对于局部变量,如在定义时不初始化而直接使用,则编译时就会报错,因为Java中要求所有的局部变量在使用之前都必须要初始化。

1 /**
 2     @author   zst
 3     @version  1.0
 4     
 5 */
 6 public class A{
 7       //没有初始化的数据成员
 8       private int i;
 9       private String s;
10       private double d;
11       
12       //无参构造函数
13       public A(){
14       
15       }
16       
17       
18       public void f(){
19       
20         System.out.println("没有初始化的数据成员,系统赋予默认值,可以直接使用");
21         System.out.println(i);
22         System.out.println(s);
23         System.out.println(d);
24         
25       }
26  
27     public void g()
28     {
29         int i = 100;    //局部变量:在使用之前必须要初始化,否则编译出错
30         System.out.println("局部变量使用之前必须要初始化  " + i); 
31     }
32     
33 }
34 /**
35     @author   zst
36     @version  1.0
37     
38 */
39 public class ConstructorTest04{
40     public static void main(String[] args){
41         
42         A aa1 = new A(); 
43         aa1.f();
44         aa1.g();   
45         
46     }
47     
48     
49 }
50 /*
51     输出:
52         没有初始化的数据成员,系统赋予默认值,可以直接使用
53         0
54         null
55         0.0
56         局部变量使用之前必须要初始化  100
57         
58 */