构造方法名([参数列表]){
? [this([参数列表]);] |[super([参数列表]);
? 语句序列
}
<p style="text-indent: 21.25pt;">其中,this是调用其他的构造方法,super是调用父类的构造方法。它们都必须放在其他语句的前面。
??●???? 构造方法的名字必须和类的名字完全相同。
??●???? 除了访问权修饰符之外,不能有其他任何修饰符,也就不能有返回值。
??●???? 尽管没有返回值,但并不能用“void”修饰。
??●???? 构造方法不能用static和final来修饰。一般也不用private修饰,这会导致无法在外部创建对象。
??●???? 构造方法不能由对象显式地调用。一般通过new关键字来调用,或者用this、super来调用。
??●???? 构造方法的参数列表可以为空,也可以有参数。根据参数的有无,可以将构造方法分为无参数的构造方法和带参数的构造方法。
??●???? 用户定义的类可以拥有多个构造方法,但要求参数列表不同。
??●???? 如果用户定义的类未提供任何构造方法时,系统会自动为其提供一个无参数的构造方法。
<h3>3.6.1? 无参数构造方法的定义和使用</h3>
<p style="text-indent: 21.25pt;">定义一个无参数的构造方法,从语法上来讲很简单,请看下面的示例。
<p style="text-indent: 21.25pt;">//-----------文件名constructNoPara.java,程序编号3.31-----------------
public class constructNoPara{
? private int? x = 0;
? //定义一个无参数的构造方法,它必须和类同名
? public constructNoPara(){
??? System.out.println("这是无参数的构造方法");
??? x = 100;???????? //为成员变量赋值
? }
? //获取成员变量x的值
? public int getX(){
??? return x;
? }
? public static void main(String args[]){
??? constructNoPara oa = new constructNoPara();?? //隐式调用无参数的构造方法
??? System.out.println("x = " + oa.getX() );?????? //输出成员变量x的值
? }
}
<p style="text-indent: 21.25pt;">注意到成员变量x,它在定义的时候已经赋了初值。在构造方法中,先是输出一条信息,然后再次为x赋值。由于构造方法的执行在定义成员变量之后,它会覆盖掉原来x的初值,所以x的值为100。程序的输出结果如下:
这是无参数的构造方法
x = 100
public class constructNoPara{
? private int? x = 0;
? //试图定义一个无参数的构造方法
? public void constructNoPara(){ //这里加了一个void
??? System.out.println("这是无参数的构造方法");
??? x = 100;???????????????????????? //为成员变量赋值
? }
? //获取成员变量x的值
? public int getX(){
??? return x;
? }
? public static void main(String args[]){
??? constructNoPara oa = new constructNoPara();?? //隐式调用无参数的构造方法
??? System.out.println("x = " + oa.getX() );?????? //输出成员变量x的值
? }
}
<p style="text-indent: 21.25pt;">这个程序仍然可以通过编译,但运行结果可能会出人意料。它的输出结果如下:
x = 0
<p style="text-indent: 21.25pt;">语句“constructNoPara oa = new constructNoPara();”并不是调用程序员自己定义的“构造方法”,而是调用了系统提供的默认的无参数的构造方法,这个方法其实什么事情也没做,自然也就不会更改x的值。
%说明:C++程序员不会犯此类错误。因为在C++中,如果在构造方法前面加上void,编译器将报错。
%注意:构造方法前的访问权限修饰符同样有4种,但通常不会是private类型。因为用它来修饰的话,无法在外部使用该构造方法。
<h3>3.6.2? 带参数构造方法的定义和使用</h3>
<p style="text-indent: 21.25pt;">Java规定,如果程序员一个构造方法都不定义,那么系统会自动为其加上一个不带参数的构造方法。如果程序员至少定义了一个构造方法,那么系统不会再提供不带参数的构造方法。
<p style="text-indent: 21.25pt;">【例3.21】带参数的构造方法示例。
public class constructWithPara{
? private int? x = 0;
? //定义一个带参数的构造方法
? public? constructWithPara(int ix){
??? System.out.println("这是带参数的构造方法");
??? x = ix;???????? //为成员变量赋值
? }
? //获取成员变量x的值
? public int getX(){
??? return x;
? }
? public static void main(String args[]){
??? constructWithPara oa = new constructWithPara(100);?? //隐式调用带参数的<br>??? ??????????????????????????????????????????????????? ??? 构造方法
??? System.out.println("x = " + oa.getX() );
? }
}
<p style="text-indent: 21.25pt;">这个程序的流程和程序3.31完全一样,只是其中的构造方法多了一个参数而已。程序运行的结果如下:
这是带参数的构造方法
x = 100
<span style="color: #0000ff;">[b]constructWithPara oa = new constructWithPara();[/b]</span>
<p style="text-indent: 0cm;"><span style="color: #0000ff;">[b]试图使用x的默认值。但这样是无法通过编译的,因为系统不会再为constructWithPara类提供无参数的构造方法。当此类被其他类继承时,这一问题显得越发严重,它甚至会导致根本无法写出一个子类。[/b]</span>
<p style="text-indent: 21.25pt;">//-----------文件名constructWithPara.java,程序编号3.33-----------------
public class constructWithPara{
? private int? x = 0;
? //定义一个带参数的构造方法
? public? constructWithPara(int ix){
??? System.out.println("这是带参数的构造方法");
??? x = ix;???????? //为成员变量赋值
? }
? //定义一个不带参数的构造方法
? public constructWithPara(){
? }
? //获取成员变量x的值
? public int getX(){
??? return x;
? }
? public static void main(String args[]){
??? constructWithPara oa = new constructWithPara(100);?? //隐式调用带参数的<br>???????????????????????????????????????????????????????????????????? 构造方法
??? System.out.println("x = " + oa.getX() );
? }
}
<h3>3.6.3? this关键字和构造方法的调用</h3>
this([参数列表])
<p style="text-indent: 21.25pt;">系统将根据参数列表来决定调用哪一个构造方法。使用this时还需注意下面几点:
??●???? 用this调用构造方法时,该语句只能用在构造方法中。
??●???? this语句必须是构造方法中的第一条语句。
??●???? 和new不同,this虽然可以调用构造方法,但它只是执行构造方法中的语句,并不会创建对象。
<p style="text-indent: 21.25pt;">这里仍然使用程序3.33,并在无参数的构造方法中加上this语句来为x赋初值。
<p style="line-height: 11pt;">public class constructWithPara{
<p style="line-height: 11pt;">? //定义一个带参数的构造方法
<p style="line-height: 11pt;">??? System.out.println("这是带参数的构造方法");
<p style="line-height: 11pt;">? }
<p style="line-height: 13pt;">? public constructWithPara(){
<p style="line-height: 13pt;">??? System.out.println("这是无参数的构造方法");
<p style="line-height: 13pt;">? //获取成员变量x的值
<p style="line-height: 13pt;">??? return x;
<p style="line-height: 13pt;">? public static void main(String args[]){
<p style="line-height: 13pt;">??? System.out.println("x = " + oa.getX() );
<p style="line-height: 13pt;">}
这是带参数的构造方法
这是无参数的构造方法
x = 100
<p style="text-indent: 21.25pt;">在constructWithPara()方法中,特别注意不要写成下面这个样子:
public constructWithPara(){
? System.out.println("这是无参数的构造方法");
? this(100);???? //调用带参数的构造方法为x赋值
}
<p style="text-indent: 21.25pt;">读者可能会觉得程序3.34用this调用另外一个构造方法为x赋值过于麻烦,不如直接为x赋值更简单。当然,这只是一个示例程序,这么做的原因在于:很多情况下,多个构造方法可能会做相同的事情,只是参数有点区别,这就可以将这段相同的代码单独抽取出来成为一个构造方法,然后使用this来调用它。
? [this([参数列表]);] |[super([参数列表]);
? 语句序列
}
<p style="text-indent: 21.25pt;">其中,this是调用其他的构造方法,super是调用父类的构造方法。它们都必须放在其他语句的前面。
??●???? 构造方法的名字必须和类的名字完全相同。
??●???? 除了访问权修饰符之外,不能有其他任何修饰符,也就不能有返回值。
??●???? 尽管没有返回值,但并不能用“void”修饰。
??●???? 构造方法不能用static和final来修饰。一般也不用private修饰,这会导致无法在外部创建对象。
??●???? 构造方法不能由对象显式地调用。一般通过new关键字来调用,或者用this、super来调用。
??●???? 构造方法的参数列表可以为空,也可以有参数。根据参数的有无,可以将构造方法分为无参数的构造方法和带参数的构造方法。
??●???? 用户定义的类可以拥有多个构造方法,但要求参数列表不同。
??●???? 如果用户定义的类未提供任何构造方法时,系统会自动为其提供一个无参数的构造方法。
<h3>3.6.1? 无参数构造方法的定义和使用</h3>
<p style="text-indent: 21.25pt;">定义一个无参数的构造方法,从语法上来讲很简单,请看下面的示例。
<p style="text-indent: 21.25pt;">//-----------文件名constructNoPara.java,程序编号3.31-----------------
public class constructNoPara{
? private int? x = 0;
? //定义一个无参数的构造方法,它必须和类同名
? public constructNoPara(){
??? System.out.println("这是无参数的构造方法");
??? x = 100;???????? //为成员变量赋值
? }
? //获取成员变量x的值
? public int getX(){
??? return x;
? }
? public static void main(String args[]){
??? constructNoPara oa = new constructNoPara();?? //隐式调用无参数的构造方法
??? System.out.println("x = " + oa.getX() );?????? //输出成员变量x的值
? }
}
<p style="text-indent: 21.25pt;">注意到成员变量x,它在定义的时候已经赋了初值。在构造方法中,先是输出一条信息,然后再次为x赋值。由于构造方法的执行在定义成员变量之后,它会覆盖掉原来x的初值,所以x的值为100。程序的输出结果如下:
这是无参数的构造方法
x = 100
public class constructNoPara{
? private int? x = 0;
? //试图定义一个无参数的构造方法
? public void constructNoPara(){ //这里加了一个void
??? System.out.println("这是无参数的构造方法");
??? x = 100;???????????????????????? //为成员变量赋值
? }
? //获取成员变量x的值
? public int getX(){
??? return x;
? }
? public static void main(String args[]){
??? constructNoPara oa = new constructNoPara();?? //隐式调用无参数的构造方法
??? System.out.println("x = " + oa.getX() );?????? //输出成员变量x的值
? }
}
<p style="text-indent: 21.25pt;">这个程序仍然可以通过编译,但运行结果可能会出人意料。它的输出结果如下:
x = 0
<p style="text-indent: 21.25pt;">语句“constructNoPara oa = new constructNoPara();”并不是调用程序员自己定义的“构造方法”,而是调用了系统提供的默认的无参数的构造方法,这个方法其实什么事情也没做,自然也就不会更改x的值。
%说明:C++程序员不会犯此类错误。因为在C++中,如果在构造方法前面加上void,编译器将报错。
%注意:构造方法前的访问权限修饰符同样有4种,但通常不会是private类型。因为用它来修饰的话,无法在外部使用该构造方法。
<h3>3.6.2? 带参数构造方法的定义和使用</h3>
<p style="text-indent: 21.25pt;">Java规定,如果程序员一个构造方法都不定义,那么系统会自动为其加上一个不带参数的构造方法。如果程序员至少定义了一个构造方法,那么系统不会再提供不带参数的构造方法。
<p style="text-indent: 21.25pt;">【例3.21】带参数的构造方法示例。
public class constructWithPara{
? private int? x = 0;
? //定义一个带参数的构造方法
? public? constructWithPara(int ix){
??? System.out.println("这是带参数的构造方法");
??? x = ix;???????? //为成员变量赋值
? }
? //获取成员变量x的值
? public int getX(){
??? return x;
? }
? public static void main(String args[]){
??? constructWithPara oa = new constructWithPara(100);?? //隐式调用带参数的<br>??? ??????????????????????????????????????????????????? ??? 构造方法
??? System.out.println("x = " + oa.getX() );
? }
}
<p style="text-indent: 21.25pt;">这个程序的流程和程序3.31完全一样,只是其中的构造方法多了一个参数而已。程序运行的结果如下:
这是带参数的构造方法
x = 100
<span style="color: #0000ff;">[b]constructWithPara oa = new constructWithPara();[/b]</span>
<p style="text-indent: 0cm;"><span style="color: #0000ff;">[b]试图使用x的默认值。但这样是无法通过编译的,因为系统不会再为constructWithPara类提供无参数的构造方法。当此类被其他类继承时,这一问题显得越发严重,它甚至会导致根本无法写出一个子类。[/b]</span>
<p style="text-indent: 21.25pt;">//-----------文件名constructWithPara.java,程序编号3.33-----------------
public class constructWithPara{
? private int? x = 0;
? //定义一个带参数的构造方法
? public? constructWithPara(int ix){
??? System.out.println("这是带参数的构造方法");
??? x = ix;???????? //为成员变量赋值
? }
? //定义一个不带参数的构造方法
? public constructWithPara(){
? }
? //获取成员变量x的值
? public int getX(){
??? return x;
? }
? public static void main(String args[]){
??? constructWithPara oa = new constructWithPara(100);?? //隐式调用带参数的<br>???????????????????????????????????????????????????????????????????? 构造方法
??? System.out.println("x = " + oa.getX() );
? }
}
<h3>3.6.3? this关键字和构造方法的调用</h3>
this([参数列表])
<p style="text-indent: 21.25pt;">系统将根据参数列表来决定调用哪一个构造方法。使用this时还需注意下面几点:
??●???? 用this调用构造方法时,该语句只能用在构造方法中。
??●???? this语句必须是构造方法中的第一条语句。
??●???? 和new不同,this虽然可以调用构造方法,但它只是执行构造方法中的语句,并不会创建对象。
<p style="text-indent: 21.25pt;">这里仍然使用程序3.33,并在无参数的构造方法中加上this语句来为x赋初值。
<p style="line-height: 11pt;">public class constructWithPara{
<p style="line-height: 11pt;">? //定义一个带参数的构造方法
<p style="line-height: 11pt;">??? System.out.println("这是带参数的构造方法");
<p style="line-height: 11pt;">? }
<p style="line-height: 13pt;">? public constructWithPara(){
<p style="line-height: 13pt;">??? System.out.println("这是无参数的构造方法");
<p style="line-height: 13pt;">? //获取成员变量x的值
<p style="line-height: 13pt;">??? return x;
<p style="line-height: 13pt;">? public static void main(String args[]){
<p style="line-height: 13pt;">??? System.out.println("x = " + oa.getX() );
<p style="line-height: 13pt;">}
这是带参数的构造方法
这是无参数的构造方法
x = 100
<p style="text-indent: 21.25pt;">在constructWithPara()方法中,特别注意不要写成下面这个样子:
public constructWithPara(){
? System.out.println("这是无参数的构造方法");
? this(100);???? //调用带参数的构造方法为x赋值
}
<p style="text-indent: 21.25pt;">读者可能会觉得程序3.34用this调用另外一个构造方法为x赋值过于麻烦,不如直接为x赋值更简单。当然,这只是一个示例程序,这么做的原因在于:很多情况下,多个构造方法可能会做相同的事情,只是参数有点区别,这就可以将这段相同的代码单独抽取出来成为一个构造方法,然后使用this来调用它。