一、构造器的作用
- 创建对象
- 初始化对象的信息
二、特点
- 定义构造器的格式:
权限修饰符 类名(形参列表){}
- 构造器名与类名相同
- 不能有返回值(返回值也不能为void)
- 不可以写return语句
- 当开发人员没有提供构造函数时,编译器在把源代码编译成字节码的过程中会提供一个没有参数默认的构造器,但该构造器不会执行任何代码。如果开发人员提供了构造函数,那么编译器就不会再创建默认的构造器了
- 字节码出现的地方:使用javac PersonDemo.java指令编译示例代码,会产生两个字节码文件:Person.class与PersonDemo.class
- 构造器不能被继承,因此,它不能被覆盖,但是构造器能够被重载,可以使用不同参数个数或参数类型来定义多个构造器
class Person{
Person(){
System.out.println("person run");
}
}
public class PersonDemo {
public static void main(String[] args) {
Person p = new Person();
}//输出结果:person run
}
- 构造器总是伴随着new操作一起调用,且不能由程序编写者直接调用,必须要由系统调用。构造器在对象实例化时会被自动调用,且只运行一次;而普通的方法是在程序执行到它时被调用,且可以被该对象调用多次。
三、什么时候定义构造器?
当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造器中。
四、子父类中构造器的特点
class Fu{
public Fu() {
System.out.println("Fu run");
}
}
class Zi extends Fu{
public Zi() {
System.out.println("Zi run");
}
}
public class test {
public static void main(String[] args) {
Zi z = new Zi();
}
}
提问1.:为什么只对子类对象初始化时,父类的构造器也会运行?
public Zi() {
//super();
System.out.println("Zi run");
}
结论1.:虚拟机默认在子类构造方法的第一行提供了隐式的super();该句会访问父类中空参数的构造方法。而且子类中所有的构造方法默认第一行都是super();当然,子类的构造方法第一行也可以手动指定this语句来访问本类中的构造方法;子类中至少会有一个构造方法访问父类中构造方法。
提问2.:为什么子类一定要访问父类中的构造方法?
结论2.:因为父类中的数据子类可以直接获取,所以子类对象在建立时,需要先查看父类是如何对这些数据初始 化的,所以子类在对象初始化时,要先访问父类中的构造方法。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
五、引申:普通方法是否可以与构造器有相同的方法名?
public class test {
public test(){
System.out.println("construct");
}
public void test() {
System.out.println("call test");
}
public static void main(String[] args) {
test t = new test();//调用构造方法
t.test();//调用test方法
}
}
答案是可以的: