[ 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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端知识分享

第164天:js方法调用的四种模式

函数名提升: script中脚本,在执行之前,会先把脚本中的所有的函数先进行编译解析,然后执行普通的js代码。

962
来自专栏计算机视觉

Python 函数使用记录,join函数和os.path.join用法

1.join()函数 语法:‘sep’.join(seq) 参数说明: sep:分隔符。可以为空 seq:要连接的元素序列、字符串、元组、字典等 上面的语法即:...

2887
来自专栏开源优测

[快学Python3]if条件控制

if语句 先看下Python中一般的条件控制语句的形式是怎么样的,如下所示: if 条件: # 代码块 elif 条件: ...

1984
来自专栏吾爱乐享

java之学习vector类的特有功能

1292
来自专栏desperate633

LintCode 两个字符串是变位词题目分析代码

写出一个函数 anagram(s, t) 判断两个字符串是否可以通过改变字母的顺序变成一样的字符串。

912
来自专栏我爱编程

Day7函数式编程3/3

装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。 >>> def now(): ... print('2018...

3747
来自专栏Vamei实验室

Python基础03 序列

sequence 序列 sequence(序列)是一组有顺序的元素的集合 (严格的说,是对象的集合,但鉴于我们还没有引入“对象”概念,暂时说元素) 序列可以包含...

1955
来自专栏python读书笔记

python 数据分析基础 day2-数值及字符串数值字符串

今天说一下python 的内置的数据类型以及相应的操作方法 数值 数值类型主要有整数(int)、浮点数(flooat)、长整数(long)、复数(complex...

32810
来自专栏深度学习思考者

一文搞懂C/C++中指针那些事(上篇)

一 指针变量 1.间接存取        指针变量的值为地址;普通变量的值为数据;其中“*”为指针运算符。&是地址操作符,用来引用一个内存地址。通过在变量名...

21310
来自专栏和蔼的张星的图像处理专栏

50. 数组剔除元素后的乘积两个遍历

给定一个整数数组A。 定义B[i] = A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1], 计算B的时候请不要使用除法。...

1134

扫码关注云+社区

领取腾讯云代金券