首页 > 编程笔记

Java构造方法(构造函数)

在 Java 中,构造方法也叫作构造函数或构造器,它的名字必须和所在类的名字一致,不能在其中声明 void,访问权限可以为任意,可以是 public,也可以是 protected 或者 private,但是一般情况下使用 public 权限。

构造方法的名字和类名相同,也就是在类中和类名相同的方法一定是构造方法,比如创建了 Cat 类,那么构造方法的名称也应该叫作 Cat。

构造方法中的形式参数可以根据需要自行定义,参数不同的构造方法就是构造方法的重载,就像之前所遇到的方法重载一样。

构造方法什么时候会被调用呢?当程序中没有编写构造方法时,Java 会自动创建构造方法,但是不会通过这个构造方法执行任何语句,而且即使已经被创建和调用,我们并不能够在程序中看到它,因为它只会在 Java 内部运行,并在通过类实例化对象的时候自动被调用。

也就是说,如果不重写这个构造方法,它不会做任何事,也不会执行任何代码,在 Java 内部只会体现出一个构造方法被创建的过程,而这个过程我们是观察不到的。如果想要更改和重写这个构造方法,则可以在定义的类中重写这个构造方法(构造方法名和类名一致)。

如果我们已经自定义了一个构造方法,在其中也编写了相应自定义的程序语句,那么一旦 Java 程序中创建了该类所实例化的对象,就会立马执行这个自定义构造方法中的程序语句,因为我们已经将这个一定会被执行的构造方法进行了重写。

下面来看一个有关构造方法的例子:
public class Cat {
    public String name;      //定义成员变量name
    public String color;     //定义成员变量color
    public int age;          //定义成员变量age
    public Cat()             //增添下面这一段代码,这就是我们的构造器
    {
        System.out.println("这个是构造器中的代码");

    }
    public void eat()        //定义猫类都能够执行的方法
    {
        System.out.println("小猫"+name+"正在吃东西");
    }
    public void saycolor()
    {
        System.out.println("小猫"+name+"的颜色是"+color);
    }
    public void sayage()
    {
        System.out.println("小猫"+name+"的年龄是"+age);
    }
}
一旦利用 Cat 类生成一个新的对象,那么必然调用和执行所编写的构造器中的语句。再来看 main() 函数,验证创建对象时是否会调用构造器:
public class Main {

    public static void main(String[] args) {
      System.out.println("这是我们主类中的主方法,程序先从这里开始执行");
      Cat cat1 = new Cat();//这里创建一个Cat类中的对象cat1
    }
}
然后可以看到其输出为:

这是我们主类中的主方法,程序先从这里开始执行
这个是构造器中的代码

很显然,首先打印了“这是我们主类中的主方法,程序先从这里开始执行”,然后在新的 cat1 对象被创建的时候打印了“这个是构造器中的代码”。我们通过 Cat 类生成一个新的对象,将会直接调用构造器。那么这一点对于 Cat 的子类 SmallCat 是否适用呢?

继续改写 main 函数中的代码为:
public class Main {

    public static void main(String[] args) {
      System.out.println("这是我们主类中的主方法,程序先从这里开始执行");
      Cat cat1 = new Cat();//这里创建一个Cat类中的对象cat1
      SmallCat cat2=new SmallCat();
    }
}
输出的结果为:

这是我们主类中的主方法,程序先从这里开始执行
这个是构造器中的代码
这个是构造器中的代码

从结果中可以分析得到,因为之前子类 SmallCat 已经继承了父类中的所有属性和方法,被继承的方法中肯定同时也包含构造器,只是这个构造器的名和子类的类名相同,和父类不同,子类构造器中的内容则和父类相同。因此,一旦利用子类创建对象,也会直接调用父类中的构造器进行输出。

当然,也可以像之前所做的那样,在子类中直接对父类的方法进行改写,这个对构造器也是适用的,也可以在子类中重写父类中的构造器。我们改写 SmallCat 类的代码为:
public class SmallCat extends Cat{
    public SmallCat()
    {
        System.out.println("这个是子类构造器中的代码");
    }

    public void eat()
    {
        System.out.println("小猫吃肉肉");
    }
    public void neweat()
    {
        System.out.println("小猫的儿子小猫开始吃饭了\n");
    }
}
然后再次运行主类中的代码:
public class Main {

    public static void main(String[] args) {
      System.out.println("这是我们主类中的主方法,程序先从这里开始执行");
      Cat cat1 = new Cat();//这里创建一个Cat类中的对象cat1
      SmallCat cat2=new SmallCat();
    }
}
输出结果为:

这是我们主类中的主方法,程序先从这里开始执行
这个是构造器中的代码
这个是构造器中的代码
这个是子类构造器中的代码

很显然,由于我们改写了子类中构造器的代码,因此在创建子类对象时会调用子类构造器中的代码。

推荐阅读