Java基础教程之构造器与方法重载

在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initialization)。初始化时,对象的数据成员被赋予初始值。我们可以显式初始化。如果我们没有给数据成员赋予初始值,数据成员会根据其类型采用默认初始值。

显式初始化要求我们在写程序时就确定初始值,这有时很不方便。我们可以使用构造器(constructor)来初始化对象。构造器可以初始化数据成员,还可以规定特定的操作。这些操作会在创建对象时自动执行。

定义构造器

构造器是一个方法。像普通方法一样,我们在类中定义构造器。构造器有如下基本特征:

1.构造器的名字和类的名字相同
2.构造器没有返回值
 
我们定义Human类的构造器:

public class Test
{
  public static void main(String[] args)
  {
    Human aPerson = new Human(160);
    System.out.println(aPerson.getHeight());
  }

}

class Human
{
  /**
   * constructor
   */
  Human(int h)
  {
    this.height = h;
    System.out.println("I'm born");
  }

  /**
   * accessor
   */
  int getHeight()
  {
    return this.height;
  }

  int height;
}

上面的程序会打印

代码如下:

I'm born
160

构造器可以像普通方法一样接收参数列表。这里,构造器Human()接收一个整数作为参数。在方法的主体中,我们将该整数参数赋予给数据成员height。构造器在对象创建时做了两件事:

构造器可以像普通方法一样接收参数列表。这里,构造器Human()接收一个整数作为参数。在方法的主体中,我们将该整数参数赋予给数据成员height。构造器在对象创建时做了两件事:

1.为数据成员提供初始值 this.height = h;
2.执行特定的初始操作 System.out.println("I'm born");

这样,我们就可以在调用构造器时,灵活的设定初始值,不用像显示初始化那样拘束。

构造器是如何被调用的呢?我们在创建类的时候,采用的都是new Human()的方式。实际上,我们就是在调用Human类的构造器。当我们没有定义该方法时,Java会提供一个空白的构造器,以便使用new的时候调用。但当我们定义了构造器时,在创建对象时,Java会调用定义了的构造器。在调用时,我们提供了一个参数160。从最后的运行结果中也可以看到,对象的height确实被初始化为160。

初始化方法的优先级

在方法与数据成员中,我们可以看到,如果我们提供显式初始值,那么数据成员就会采用显式初始值,而不是默认初始值。但如果我们既提供显式初始值,又在构造器初始化同一数据成员,最终的初始值将由构造器决定。比如下面的例子:

public class Test
{
  public static void main(String[] args)
  {
    Human aPerson = new Human(160);
    System.out.println(aPerson.getHeight());
  }

}

class Human
{
  /**
   * constructor
   */
  Human(int h)
  {
    this.height = h;
  }

  /**
   * accessor
   */
  int getHeight()
  {
    return this.height;
  }

  int height=170; // explicit initialization
}

运行结果为:

代码如下:

160

对象最终的初始化值与构建方法中的值一致。因此:

构建方法 > 显式初始值 > 默认初始值

(事实上,所谓的优先级与初始化时的执行顺序有关,我将在以后深入这一点)

方法重载

一个类中可以定义不止一个构造器,比如:

public class Test
{
  public static void main(String[] args)
  {
    Human neZha  = new Human(150, "shit");
    System.out.println(neZha.getHeight());
  }

}

class Human
{
  /**
   * constructor 1
   */
  Human(int h)
  {
    this.height = h;
    System.out.println("I'm born");
  }

  /**
   * constructor 2
   */
  Human(int h, String s)
  {
    this.height = h;
    System.out.println("Ne Zha: I'm born, " + s);
  }

  /**
   * accessor
   */
  int getHeight()
  {
    return this.height;
  }

  int height;
}

运行结果:

代码如下:

Ne Zha: I'm born, shit
150

上面定义了两个构造器,名字都是Human。两个构造器有不同的参数列表。

在使用new创建对象时,Java会根据提供的参数来决定构建哪一个构造器。比如在构建neZha时,我们提供了两个参数: 整数150和字符串"shit",这对应第二个构建方法的参数列表,所以Java会调用第二个构建方法。

在Java中,Java会同时根据方法名和参数列表来决定所要调用的方法,这叫做方法重载(method overloading)。构建方法可以进行重载,普通方法也可以重载,比如下面的breath()方法:

public class Test
{
  public static void main(String[] args)
  {
    Human aPerson = new Human();
    aPerson.breath(10);
  }

}

class Human
{
  /**
    * breath() 1
    */
  void breath()
  {
    System.out.println("hu...hu...");
  }

  /**
  * breath() 2
  */
  void breath(int rep)
  {
    int i;
    for(i = 0; i < rep; i++) {
      System.out.println("lu...lu...");
    }
  }

  int height;
}

运行结果:

代码如下:

lu...lu...
lu...lu...
lu...lu...
lu...lu...
lu...lu...
lu...lu...
lu...lu...
lu...lu...
lu...lu...
lu...lu...

可以看到,由于在调用的时候提供了一个参数: 整数10,所以调用的是参数列表与之相符的第二个breath()方法。

总结

constructor特征: 与类同名,无返回值
constructor目的: 初始化,初始操作
方法重载: 方法名 + 参数列表 -> 实际调用哪一个方法

(0)

相关推荐

  • 使用Java构造和解析Json数据的两种方法(详解二)

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面接着介绍用org.json构造和解析Json数据的方法

  • Java构造器使用方法及注意事项

    Java构造器使用方法及注意事项 超类的构造器在子类的构造器运行之前运行,也就是说,在创建对象时,先运行超类中的构造器,然后再运行子类中的构造器,此时,如果在执行超类构造器的时候,构造器执行了可覆盖的方法,那么就会去调用子类中的该方法,而此时子类还未被实例化,此时就有可能出问题. 以一个例子说明: public class Super { int age = 10; protected void say() { System.out.println("super"); } public

  • Java私有构造器使用方法示例

    构造器作为Java类的一个特殊的成员同样可以设置关键字来控制其访问权限.在大多数情况下,我们一般把构造器设置为公有成员,即public的,在默认情况下,如果不写任何关键字,其访问权限也是public.这样,在我们新建一个类的对象的时候,构造器会创建对象后被自动调用,发生在其他类成员被设置为默认初始值之后,当然如果有字段初始器和初始化块的话,构造器的调用会发生在此之后.构造器的主要作用是在new将对象的引用返回之前初始化对象. 言归正传,什么叫私有构造器.所谓私有构造器,就是用private关键字

  • 简单谈谈java中匿名内部类构造函数

    先看看下面的代码能不能编译通过: public static void main(String[] args) { List l1 = new ArrayList(); List l2 = new ArrayList(){}; List l3 = new ArrayList(){{}}; System.out.println(l1.getClass() == l2.getClass() ); System.out.println(l2.getClass() == l3.getClass() );

  • java 用泛型参数类型构造数组详解及实例

    java 用泛型参数类型构造数组详解及实例 前言: 前一阵子打代码的时候突然想到一个问题.平时我们的数组都是作为一个参数传入方法中的,如果我们要想在方法中创建一个数组怎么样呢?在类型明确的情况下,这是没什么难度的.如果我们传入的参数是泛型类型的参数呢? public static <T> T[] creArray (T obj){ T[] arr = new T[10]; } 像上面这种用T来直接new数组的方法是错误的,会编译时出现一个:Cannot create a generic arr

  • 深入浅析Java中普通代码块、构造代码块与静态代码块

    //执行顺序:(优先级从高到低.) 静态代码块>mian方法>构造代码块>构造方法. 其中静态代码块只执行一次.构造代码块在每次创建对象是都会执行. 1.普通代码块 public static void main(String[] args) { /*普通代码块: *直接定义在在方法或语句中出现"{普通代码的执行语句}"的就称为普通代码块. *普通代码块执行顺序由他们在代码中出现的次序决定--"先出现先执行" * */ { System.out.p

  • Java基础教程之构造器与方法重载

    在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initialization).初始化时,对象的数据成员被赋予初始值.我们可以显式初始化.如果我们没有给数据成员赋予初始值,数据成员会根据其类型采用默认初始值. 显式初始化要求我们在写程序时就确定初始值,这有时很不方便.我们可以使用构造器(constructor)来初始化对象.构造器可以初始化数据成员,还可以规定特定的操作.这些操作会在创建对象时自动执行. 定义构造器 构造器是一个方法.像普通方法一样,我们在类中定义构造器.构造

  • Java基础教程之对象的方法与数据成员

    在Java基础教程之从Hello World到面向对象一文中,我们初步了解了对象(object).对象中的数据成员表示对象的状态.对象可以执行方法,表示特定的动作. 此外,我们还了解了类(class).同一类的对象属于相同的类型(type).我们可以定义类,并使用该定义来产生对象. 我们进一步深入到对象.了解Java中方法与数据成员的一些细节. 调用同一对象的数据成员 方法可以调用该对象的数据成员.比如下面我们给Human类增加一个getHeight()的方法.该方法返回height数据成员的值

  • Java基础第三篇 构造器与方法重载

    目录 1.定义构造器 2.初始化方法的优先级 3.方法重载 4.总结 在方法与数据成员中,我们提到,Java中的对象在创建的时候会初始化(initialization).初始化时,对象的数据成员被赋予初始值.我们可以显式初始化.如果我们没有给数据成员赋予初始值,数据成员会根据其类型采用默认初始值.显式初始化要求我们在写程序时就确定初始值,这有时很不方便.我们可以使用构造器(constructor)来初始化对象.构造器可以初始化数据成员,还可以规定特定的操作.这些操作会在创建对象时自动执行 1.定

  • Kotlin基础教程之操作符与操作符重载

    Kotlin基础教程之操作符与操作符重载 Kotlin操作符的使用方法与其他语言差不多,最大的特点就在于infix function call(事实上infix function call并不是操作符的特性,而是函数的特性)和操作符重载. 可以看到在Kotlin中大部分的操作符都与一个函数相对应,之所以这样做,大概是为了进行操作符重载. Kotlin官方文档中强调"=赋值"操作在Kotlin中不是操作符,换句话说类似于x = y = z这样的连续赋值并不被允许(甚至赋值操作也不能和常规

  • Java基础教程之数组的定义与使用

    目录 一.数组的基本概念 二.数组的声明 三.数组的创建及初始化 1.数组的创建 2.数组的初始化 四.访问数组元素 五.for each 循环 六.数组的拷贝 七.数组排序 八.二维数组 总结 一.数组的基本概念 数组是一种数据类型,用来存储同一类型值的集合,它在内存中是一段连续的空间.通过一个整形下标(index,或者称之为索引)可以访问数组中的每一个值.例如,如果a是一个整型数组,a[i]就是一个下标为i的一个整数,数组是一种引用类型. 二.数组的声明 声明数组变量时,需要指出数组类型(数

  • Java基础教程之获取操作系统及浏览器信息

    目录 User Agent 的含义 浏览器的 UA 字串 UserAgentUtils.jar 通过(User-Agent)获取 浏览器类型,操作系统类型,手机机型 再给出一个: 总结 在生产环境下,我们需要关闭swagger配置,避免暴露接口的这种危险行为. User Agent 的含义 User Agent 中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本.CPU 类型.浏览器及版本.浏览器渲染引擎.浏览器语言.浏览器插件等. 一些网站常常通过判

  • Java基础教程之整数运算

    目录 引言 溢出 自增/自减 移位运算 位运算 运算优先级 类型的自动提升与强制转型 练习 小结 总结 引言 Java的整数运算遵循四则运算规则,可以使用任意嵌套的小括号.四则运算规则和初等数学一致.例如: public class Main { public static void main(String[] args) { int i=(100+200)*(99-88);//3300 int n=7*(5+(i-9));//23072 System.out.println(i); Syste

  • Java基础教程_判断语句if else

    与三元运算符相比: 好处:可以简化if else 代码 弊端 因为是一个运算符,所以运算玩必须要有一个结果 以上这篇Java基础教程_判断语句if else就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • Java 基础:string中的compareTo方法

    目录 一,java.lang.Comparable 接口 二,java.util.Comparator 接口 三,聊聊string中的compareTo方法 前言: 今天看了一篇gitchat的文章,标题是 聊聊 Java String 源码的排序算法,从中有所感悟和思考,因此打算总结下自己看的过程中的收获 一,java.lang.Comparable 接口 Comparable 接口强制了实现类对象列表的排序.其排序称为自然顺序,其 compareTo 方法,称为自然比较法 public in

  • java基础教程之拼图游戏的实现

    目录 前言 废话不多说,直接上效果图: 1.所需技术 2.具体实现 2.1 图片制作 2.2 创建项目 2.3 编码实现 总结 前言 大家在初学java的时候,大部分的代码都是在控制台上运行的.可能大家辛辛苦苦写了几十行代码,最终就只是在控制台输出一个字符,这个时候,心里肯定是拔凉拔凉的,心中那一朵编程的火花,就马上给扑灭了.我们都知道兴趣是最好的老师.为了拯救大家快要熄灭的小火花,小编在这里给大家带来使用java做个小游戏,并且通过做这个游戏,好好收悉一下面向对象的实际使用. 废话不多说,直接

随机推荐