[ Java学习基础 ] Java构造函数

     构造方法是类中特殊方法,用来初始化类的实例变量,它在创建对象(new运算符)之后自动调用。

Java构造方法的特点如下:

  1. 构造方法名必须与类名相同。

  2. 构造方法没有任何返回值,包括void。

  3. 构造方法只能与new运算符结合使用。

示例代码如下:

 1 //Rectangle.java文件
 2 package com.a51work6;
 3 
 4 // 矩形类
 5 public class Rectangle {
 6 
 7     // 矩形宽度
 8     int width;
 9     // 矩形高度
10     int height;
11     // 矩形面积
12     int area;
13 
14     // 构造方法
15     public Rectangle(int w, int h) {        
16         width = w;
17         height = h;
18         area = getArea(w, h);
19     }
20     ...
21 }

代码第15行是声明了一个构造方法,其中有两个参数w和h,用来初始化Rectangle对象的两个成员变量width和height,注意前面没有任何的返回值。

默认构造方法

有时在类中根本看不到任何的构造方法。例如本节中User类代码如下:

 1 //User.java文件
 2 package com.a51work6;
 3 
 4 public class User {
 5 
 6     // 用户名
 7     private String username;
 8 
 9     // 用户密码
10     private String password;
11 
12 }

从上述User类代码,只有两个成员变量,看不到任何的构造方法,但是还是可以调用无参数的构造方法创建User对象,因为Java虚拟机会为没有构造方法的类,提供一个无参数的默认构造方法,默认构造方法其方法体内无任何语句,默认构造方法相当于如下代码:

//默认构造方法
public User() {
}

默认构造方法的方法体内无任何语句,也就不能够初始化成员变量了,那么这些成员变量就会使用默认值,成员变量默认值是与数据类型有关。

构造方法重载

      在一个类中可以有多个构造方法,它们具体有相同的名字(与类名相同),参数列表不同,所以它们之间一定是重载关系。

构造方法重载示例代码如下:

 1 //Person.java文件
 2 package com.a51work6;
 3 
 4 import java.util.Date;
 5 
 6 public class Person {
 7 
 8     // 名字
 9     private String name;
10     // 年龄
11     private int age;
12     // 出生日期
13     private Date birthDate;
14 
15     public Person(String n, int a, Date d) {        
16         name = n;
17         age = a;
18         birthDate = d;
19     }
20 
21     public Person(String n, int a) {                
22         name = n;
23         age = a;
24     }
25 
26     public Person(String n, Date d) {               
27         name = n;
28         age = 30;
29         birthDate = d;
30     }
31 
32     public Person(String n) {                       
33         name = n;
34         age = 30;
35     }
36 
37     public String getInfo() {
38         StringBuilder sb = new StringBuilder();
39         sb.append("名字: ").append(name).append('\n');
40         sb.append("年龄: ").append(age).append('\n');
41         sb.append("出生日期: ").append(birthDate).append('\n');
42         return  sb.toString();
43     }
44 }

上述代码Person类代码提供了4个重载的构造方法,如果有准确的姓名、年龄和出生日期信息,则可以选用代码第15行的构造方法创建Person对象;如果只有姓名和年龄信息则可选用代码第21行的构造方法创建Person对象;如果只有姓名和出生日期信息则可选用代码第26行的构造方法创建Person对象;如果只有姓名信息则可选用代码第32行的构造方法创建Person对象。

Tips:如果在类中添加了带参的构造函数,系统就不会在自动生成无参的构造函数,所以建议添加带参数的构造函数后,再手动添加一个默认无参的构造函数。

构造方法封装

构造方法也可以进行封装,访问级别与普通方法一样,构造方法的访问级别参考[ Java学习基础 ] Java的封装性与访问控制中图所示。示例代码如下:

 1 //Person.java文件
 2 package com.a51work6;
 3 
 4 import java.util.Date;
 5 
 6 public class Person {
 7 
 8     // 名字
 9     private String name;
10     // 年龄
11     private int age;
12     // 出生日期
13     private Date birthDate;
14 
15     // 公有级别限制
16     public Person(String n, int a, Date d) {        
17         name = n;
18         age = a;
19         birthDate = d;
20     }
21 
22     // 默认级别限制
23     Person(String n, int a) {                       
24         name = n;
25         age = a;
26     }
27 
28     // 保护级别限制
29     protected Person(String n, Date d) {            
30         name = n;
31         age = 30;
32         birthDate = d;
33     }
34 
35     // 私有级别限制
36     private Person(String n) {                      
37         name = n;
38         age = 30;
39     }
40 
41     ...
42 }

上述代码第16行是声明公有级别的构造方法。代码第23行是声明默认级别,默认级别只能在同一个包中访问。代码第29行是保护级别的构造方法,该构造方法在同一包中与默认级别相同,在不同包中可以被子类继承。代码第36行是私有级别构造方法,该构造方法只能在当前类中使用,不允许在外边访问,私有构造方法可以应用于单例设计模式等设计。

----------------------------------------------------------------------------

初始化块和构造函数的执行顺序

读者可先自行阅读下面代码,判断输出结果:

 1   class B extends Object
 2   {
 3       static
 4       {
 5           System.out.println("Load B");    
 6       }
 7       public B()
 8       {
 9             System.out.println("Create B");      
10      }
11  }    
12  class A extends B
13  {
14      static
15      {
16          System.out.println("Load A");
17      }
18      public A()
19      {
20          System.out.println("Create A");
21      }
22  }
23  
24  public class Testclass
25  {
26      public static void main(String [] args)
27      {
28          new A();
29      }
30  }

输出结果:

Load B
Load A
Create B
Create A

      初始化块在构造器执行之前执行,类初始化阶段先执行最顶层父类的静态初始化块,依次向下执行,最后执行当前类的静态初始化块;创建对象时,先调调用顶层父类的构造方法,依次向下执行,最后调用本类的构造方法 。所以执行顺序为:父类静态代码 -> 子类静态代码块 -> 父类构造代码块 -> 父类构造函数 -> 子类构造代码块 -> 子类构造函数

 

posted @ 2018-04-22 18:02  Kevin.ZhangCG  阅读(672)  评论(0编辑  收藏  举报