Java:类的构造函数
类的构造函数
- 类的构造函数特点:
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 */