对象的前世今生(一)
文章来源:《Head First Java》修炼感悟。
现在老白总算明白了变量和对象的生存空间,下一步准备更深入地研究对象的创建。 可能好多人对新建对象没啥感觉,认为使用 new 关键字就可以简单地创建。其实这个过程还是有很多东西需要去了解的,比如说构造方法就足够老白开几篇文章去研究。 本篇文章准备讨论构造方法,请准备好,下一波知识更加猛烈!
被隐藏了的构造方法
还记得如何创建一个对象吗? 三个步骤:
- 声明引用变量;
- 创建对象;
- 关联引用变量和对象(赋值)。
// 声明 dog 变量、创建 Dog 对象并赋值
Dog dog = new Dog();
仔细看看 new Dog()
,是不是似曾相识,感觉好像在调用一个方法。 实际上你的感觉没错,的确是在调用方法,只不过这个方法比较特殊,被称作「构造方法」。构造方法特殊之处在于只能由 new
命令调用并且没有返回值,默认情况下被 Java「雪藏」。
下面看看构造方法真实的样子:
public class Dog {
// 默认的构造方法
public Dog() {
// TODO: 初始化
}
}
每个类都有一个默认的构造方法(不带参数),名字与类名相同,并且没有返回值。 当新建 Dog 对象时,首先会执行构造方法,执行结束后 Dog 对象也随之创建完成。 你可以在构造方法中做一些准备工作,比如变量初始化等等,这样就可以确保 Dog 对象被正确初始化后再赋值给引用变量 dog
。
老白感悟: 构造方法的意义在于,允许你提前介入对象创建过程,确保在对象使用前做好充分准备。
正确使用构造方法
利用以下代码进行测试,是否如上所说的构造方法会提前介入:
// 用于测试构造方法是否提前执行
public class Dog {
// 构造方法
public Dog() {
System.out.println("调用 bark() 方法:");
bark();
}
// 普通方法
private void bark() {
System.out.println("汪汪汪");
}
// 测试入口
public static void main(String[] args) {
Dog dog = new Dog();
}
}
编译测试结果:
从测试结果来看,确实是最先执行构造方法。 如果是这样的话,假设 Dog 对象有个
size
实例变量,就可以在构造方法中赋一个默认值。 只不过这样做不适合所有 Dog 对象,有没有更好的方法呢? 聪明的同学很快会想到,既然是方法,那就应该可以重载。 是的,构造方法确实可以重载,而且重载的构造方法更实用。
重载构造方法
前面我们学过,方法重载是指重新定义名称相同、参数不同的方法,Java 会根据参数列表调用对应的方法。 还是上面那个例子:
// 测试构造方法重载的例子
public class Dog {
// 实例变量
private int size;
// 默认构造方法,设置变量默认值
public Dog() {
size = 5;
}
// 重载构造方法,使用传入的参数值对变量赋值
public Dog(int size) {
this.size = size;
}
// 普通方法
public void bark() {
System.out.println("variable size is " + size);
}
// 测试入口
public static void main(String[] args) {
Dog dog = new Dog(10); // 这将执行重载过的构造方法
dog.bark();
}
}
编译执行结果:
这样一来就有了两个构造方法,使用不带参数的构造方法设置默认值,使用重载的构造方法设置自定义值。
需要注意的是,必须提供默认的构造方法(不带参数的)。 一般情况下,如果你不使用构造方法,编译器会自动为你生成一个默认构造方法,并且是隐藏的;一旦你使用了任何版本的构造方法,就必须再提供一个默认版本的,无论你使不使用都要这样做。 因为你重载了构造方法后,编译器不会再为你提供默认的构造方法。
近期重点知识回顾
- 实例变量保存在它的对象中,位于堆中;
- 如果实例变量是引用类型,则这个变量和对象都保存在堆中;
- 实例变量有默认值,0、0.0、false、null(引用类型);
- 类的构造方法在创建对象时执行;
- 构造方法与类同名并且没有返回值;
- 可以使用构造方法初始化对象的状态;
- 如果没有使用构造方法,编译器会自动创建一个默认的;
- 默认构造方法没有参数;
- 重载构造方法意味着类中存在多个构造方法;
- 如果重载了构造方法,编译器不会再提供默认构造方法;
- 设计类时,最好提供一个默认构造方法,方便设置默认值。
《 上一篇 对象的容身之处 | 下一篇 对象的前世今生(二) 》 |
---|