`
bluenemo
  • 浏览: 175654 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

构造方法,重载,多个,无参,参数,this,super

阅读更多

构造方法是类中一种特殊的方法,它一般由系统在创建对象(即类实例化)时自动调用。构造方法是对象中第一个被执行的方法,主要用于申请内存、对类的成员变量进行初始化等操作。构造方法虽然也位于类里面,但在很多情况下与普通成员方法表现不同,所以也有人认为它不是成员方法,而且将其称为“构造器”。本书仍然沿用通常的称呼,将其称为构造方法。构造方法的一般形式为:

构造方法名([参数列表]){

  [this([参数列表]);] |[super([参数列表]);

  语句序列

}

其中,this是调用其他的构造方法,super是调用父类的构造方法。它们都必须放在其他语句的前面。

编写式构造方法要注意以下几点:

  ●     构造方法的名字必须和类的名字完全相同。

  ●     除了访问权修饰符之外,不能有其他任何修饰符,也就不能有返回值。

  ●     尽管没有返回值,但并不能用“void”修饰。

  ●     构造方法不能用static和final来修饰。一般也不用private修饰,这会导致无法在外部创建对象。

  ●     构造方法不能由对象显式地调用。一般通过new关键字来调用,或者用this、super来调用。

  ●     构造方法的参数列表可以为空,也可以有参数。根据参数的有无,可以将构造方法分为无参数的构造方法和带参数的构造方法。

  ●     用户定义的类可以拥有多个构造方法,但要求参数列表不同。

  ●     如果用户定义的类未提供任何构造方法时,系统会自动为其提供一个无参数的构造方法。

3.6.1  无参数构造方法的定义和使用

定义一个无参数的构造方法,从语法上来讲很简单,请看下面的示例。

【例3.20】无参数的构造方法示例。

//-----------文件名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的值

  }

}

调用构造方法使用的是“new constructNoPara()”,这是一种隐式的调用方法,不能写成“oa.constructNoPara()”的形式。

注意到成员变量x,它在定义的时候已经赋了初值。在构造方法中,先是输出一条信息,然后再次为x赋值。由于构造方法的执行在定义成员变量之后,它会覆盖掉原来x的初值,所以x的值为100。程序的输出结果如下:

这是无参数的构造方法

x = 100

对于初学者而言,最容易犯的错误是在构造方法之前加上“void”,变成下面这个      样子:

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的值

  }

}

这个程序仍然可以通过编译,但运行结果可能会出人意料。它的输出结果如下:

x = 0

这表明,程序员自己定义的无参数的构造方法根本就没有执行。这是因为加上“void”修饰符之后,constructNoPara()不再是一个构造方法,而成了一个普通方法。

语句“constructNoPara oa = new constructNoPara();”并不是调用程序员自己定义的“构造方法”,而是调用了系统提供的默认的无参数的构造方法,这个方法其实什么事情也没做,自然也就不会更改x的值。

%说明:C++程序员不会犯此类错误。因为在C++中,如果在构造方法前面加上void,编译器将报错。

%注意:构造方法前的访问权限修饰符同样有4种,但通常不会是private类型。因为用它来修饰的话,无法在外部使用该构造方法。

3.6.2  带参数构造方法的定义和使用

在很多时候,需要根据不同的情况为成员变量赋不同的初值,这就需要传递参数给构造方法。因此,Java中允许定义带参数的构造方法,而且这种带参数的构造方法还可以定义多个(前提是参数列表有区别)这种现象被称为构造方法的重载。

Java规定,如果程序员一个构造方法都不定义,那么系统会自动为其加上一个不带参数的构造方法。如果程序员至少定义了一个构造方法,那么系统不会再提供不带参数的构造方法。

当用new来创建对象时,需要提供类型相容的参数,否则编译器将报错。

【例3.21】带参数的构造方法示例。

//-----------文件名constructWithPara.java,程序编号3.32-----------------

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);   //隐式调用带参数的
                                                            构造方法

    System.out.println("x = " + oa.getX() );

  }

}

这个程序的流程和程序3.31完全一样,只是其中的构造方法多了一个参数而已。程序运行的结果如下:

这是带参数的构造方法

x = 100

这个程序从表面上看没有什么问题,但实际上它存在着一个很大的隐患如果将类constructWithPara提供给其他的程序员使用,使用者很有可能会按照一般的习惯这么来创建一个对象:

constructWithPara oa = new constructWithPara();

试图使用x的默认值。但这样是无法通过编译的,因为系统不会再为constructWithPara类提供无参数的构造方法。当此类被其他类继承时,这一问题显得越发严重,它甚至会导致根本无法写出一个子类。

因此,强烈建议程序员在定义带参数的构造方法时,也要定义一个不带参数的构造方法,即便这个方法什么事情也不做。所以程序3.32应该改成下面这个样子:

//-----------文件名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);   //隐式调用带参数的
                                                                     构造方法

    System.out.println("x = " + oa.getX() );

  }

}

3.6.3  this关键字和构造方法的调用

在3.5.3节中,已经介绍了this关键字的作用——作为隐含参数指向本对象。其实this关键字还有一个作用,就是用来显示地调用构造方法。它的使用格式如下:

this([参数列表])

系统将根据参数列表来决定调用哪一个构造方法。使用this时还需注意下面几点:

  ●     用this调用构造方法时,该语句只能用在构造方法中。

  ●     this语句必须是构造方法中的第一条语句。

  ●     和new不同,this虽然可以调用构造方法,但它只是执行构造方法中的语句,并不会创建对象。

【例3.22】用this调用构造方法示例。

这里仍然使用程序3.33,并在无参数的构造方法中加上this语句来为x赋初值。

//-----------文件名constructWithPara.java,程序编号3.34-----------------

public class constructWithPara{

  private int  x = 0;

  //定义一个带参数的构造方法

  public  constructWithPara(int ix){

    System.out.println("这是带参数的构造方法");

    x = ix;         //为成员变量赋值

  }

  //定义一个不带参数的构造方法

  public constructWithPara(){

    this(100);     //调用带参数的构造方法为x赋值

    System.out.println("这是无参数的构造方法");

  }

  //获取成员变量x的值

  public int getX(){

    return x;

  }

  public static void main(String args[]){

    constructWithPara oa = new constructWithPara(); //隐式调用无参数的构造方法

    System.out.println("x = " + oa.getX() );

  }

}

在main()方法中利用无参数的构造方法来创建对象,而在无参数的构造方法中,用this来调用带参数的构造方法,然后再输出一条信息。程序输出结果如下:

这是带参数的构造方法

这是无参数的构造方法

x = 100

在constructWithPara()方法中,特别注意不要写成下面这个样子:

public constructWithPara(){

  System.out.println("这是无参数的构造方法");

  this(100);     //调用带参数的构造方法为x赋值

}

这样编译会出错,因为this调用构造方法只能作为第一条语句。

读者可能会觉得程序3.34用this调用另外一个构造方法为x赋值过于麻烦,不如直接为x赋值更简单。当然,这只是一个示例程序,这么做的原因在于:很多情况下,多个构造方法可能会做相同的事情,只是参数有点区别,这就可以将这段相同的代码单独抽取出来成为一个构造方法,然后使用this来调用它。

分享到:
评论

相关推荐

    java基础.txt

    重载overload的特征:在同一个类中同一个方法名,参数列表不同(个数,顺序,类型) this:关键字,对本类对象的引用,可以调用本类的属性和方法 this(); 对本类对象构造的调用,如果有参则调用有参构造 而且...

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    p1 调用缺省的构造方法(即没有参数),p2 则调用带参数的构造方法。p1、p2 分别对 应于不同的内存空间,它们的值是不同的,可以完全独立地分别对它们进行操作。虽 然 new 运算符返回对一个对象的引用,但与 C、C++中的...

    Java复习题

    B) super()和this()不一定要放在构造方法内第一行 C) this()和super()可以同时出现在一个构造函数中 D) this()和super()可以在static环境中使用,包括static方法和static语句块 ...... 一、 编写程序...

    【04-面向对象(上)】

    •如果在定义方法时,在最后一个参数的类型后增加三点…,则表明该形参接受多个参数值,多个参数值被当成数组传  入. •长度可变的形参只能位于最后一个参数,并一个方法里只能有一个可变长度的参数. 递归 •...

    常见JAVA基础_4

    1。...this和super各有什么含义? 7。试说明父类对象和子类对象的转换规则。 8。什么叫做默认构造函数? 9。在什么时候需要用到显式字段初始化? 10。如何在一个构造函数中调用另一个构造函数?

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    7.9.3 留个无参数的构造方法——给重要属性赋初始值 183 7.9.4 在构造方法中调用构造方法 184 7.10 方法大汇总 185 7.10.1 本例中用到的类 186 7.10.2 使用例程将本章的知识穿起来 189 7.11 小结:多方位理解...

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    7.9.3 留个无参数的构造方法——给重要属性赋初始值 183 7.9.4 在构造方法中调用构造方法 184 7.10 方法大汇总 185 7.10.1 本例中用到的类 186 7.10.2 使用例程将本章的知识穿起来 189 7.11 小结:多方位理解...

    Java的面向对象编程课件

     类的构造方法  new关键字的作用  缺省构造方法  方法的重载(overload)  特殊变量this  关键字static  常量的定义  类的继承  方法的覆盖(override)  特殊变量super  多态性  面向对象的程序设计

    JAVA 综合面试题.doc

     this(参数):调用本类的其他构造方法。  2. 作用域public,protected,private,以及不写时的区别?............................................. 9 Public 公有的 protected 受保护的 private 私有的 3. 编程...

    Java开发技术大全 电子版

    3.6.1无参数构造方法的定义和使用129 3.6.2带参数构造方法的定义和使用131 3.6.3this关键字和构造方法的调用132 3.7静态方法133 3.7.1静态方法的声明和定义134 3.7.2静态方法和实例方法的区别134 3.7.3静态...

    Java开发技术大全(500个源代码).

    constructNoPara.java 无参数的构造方法 constructWithPara.java 带参数的构造方法 declareDefault.java 缺省访问权限的使用 declarePrivate.java 私有访问权限的使用 declareProtected.java 保护访问权限的...

    java初学者必看

    8.2 super构造方法调用 8.3 封装和继承 8.4 使用继承 8.4.1 Object类 8.4.2 定义equals方法 8.5 关于设计好继承的几点建议 8.6 实例:一卡通类的继承 8.6.1 构造方法 8.6.2 setter方法 8.6.3 getter方法 ...

    java面试800题

    "类的初始化过程 当创建一个对象时,对象的各个变量根据其类型被设置为相应的默认初始值,然后调用构造方法,而每次调用构造方法都是要执行三个阶段: 1.调用超类的构造方法; 2.由初始化语句对给变量进行初始化...

    java 面试题 总结

    如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 15、error和exception有什么区别? error 表示恢复不是...

    JAVA语言程序设计【高清版】.pdf

    77 5.5.1 static 77 5.5.2 final和abstract 79 5.5.3 this和super 84 5.6 方法重写 86 5.6.1 方法重写概述 86 5.6.2 应用重写的规则 89 5.6.3 调用父类构造方法 89 5.7 接口 90 5.7.1 多重继承中的...

    java经典面试2010集锦100题(不看你后悔)

    C) 子类继承父类,如果父类中只有一个构造方法并且有参数,那么在子类的构造方法中必须先用super调用父类构造方法并传参。 D) 以上说法都不正确。 题目11:d 程序如下: class Test { private int day; public int...

    超级有影响力霸气的Java面试题大全文档

    如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。 18、error和exception有什么区别?  error 表示恢复...

    LuaBind 源码 (Lua增强库)

    一个函数调用中,如果函数是重载过的,并且重载函数的参数匹配分不出好坏的话 (都经行同样次数的隐式类型转换),那么将产生一个二义性错误.这将生成一个运行时 错误,程序挂起在产生二义性调用的地方.一个简单的例子是,...

    Java 基础核心总结 +经典算法大全.rar

    构造方法 方法重载 方法的重写 初始化 类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 ...

Global site tag (gtag.js) - Google Analytics