miracle just wanna be better

继承和构造函数调用的思考

2019-07-10
miracle

构造函数在有继承时的调用

使用下面例子时,修改子类和父类构造里的super的参数列表,可以看到效果

例子 :

CommenPerson.java

public class CommenPerson {
	private String name;
	private int age;
	public CommenPerson(){
		System.out.println("CommenPerson.不带参数构造");
	}
	
	public CommenPerson(String name, int age) {
		super();
		this.name = name;
		this.age = age;
		System.out.println("Student.带参数构造");
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public void study(){
		System.out.println("CommenPerson.study()");
	}
	public void eat(){
		System.out.println("CommenPerson.eat()");
	}

}

Student.java

public class Student extends CommenPerson{
	
	private String stuNo;
	public Student(){
		super();//调用父类的构造函数,如果没有写会自动添加,必须写在子类构造的第一条语句
		System.out.println("Student.不带参数构造");
	}
	
	public Student(String name,int age,String stuNo) {
		super(name,age);
		this.stuNo = stuNo;
		System.out.println("Student.带参数构造");
	}

	public String getStuNo() {
		return stuNo;
	}
	public void setStuNo(String stuNo) {
		this.stuNo = stuNo;
	}
	
	public void homework(){
		System.out.println("Student.homework");
		super.study();
	}
}

Teacher.java

public class Teacher extends CommenPerson{
	
	private int salary;
	public Teacher(){
		super();
		System.out.println("Teacher.constructor");
	}
	
	public Teacher(String name,int age,int salary) {
		super(name,age);
		this.salary = salary;
	}

	public int getSalary() {
		return salary;
	}
	public void setSalary(int salary) {
		this.salary = salary;
	}
	public void study(){
		System.out.println("Teacher.study()");
	}
	public void eat(){
		System.out.println("Teacher.eat()");
	}
	public void tech(){
		System.out.println("Teacher.tech()");
	}

Demo1.java

public class Demo1 {

	public static void main(String[] args) {
		Student stu1 = new Student("zhangsan",20,"s001");
		Teacher tea1 = new Teacher();
	}
}

在Student的有参构造函数里,把super()改成无参或者不写super,会去调用父类的无参构造方法,会导致传入参数的值一直是null或0,不能传值

结论

  1. 在Student stu1,且Student继承于commonPerson时,loadclass student类和commonPerson类进入方法区
  2. new Student();时 进入Student的构造函数,此时看构造函数第一个语句,如果该构造函数有super(),则super()先调用父类的无参构造函数,如果没有写会自动添加super();如果有super(参数列表),会先去调用父类对应参数列表的构造,执行完父类构造,父类对象出现在堆中,name=null,age=0;
  3. 执行完父类构造后,会自动回子类构造,执行子类构造,执行完毕,stuNo=null,子类对象在堆中出现
  4. 如果第二部是 new Student(“zhangsan”,20,”s001”);会先调用Student中的对应含有此参数的构造函数,然后看构造函数中的super(),然后根据参数对应去调用父类的构造函数.

总结

在new一个新对象时,先调用该类对应的构造函数,然后在构造函数里按顺序执行,第一行是super,必定先去父类调用对应的构造方法,根据super()里的参数看调用的是哪个构造函数

内存图

继承内存原理图


Comments

Content