继承中父类、子类构造器中的super. 和super()运用
1)第一种用法:super 关键字是父类对象的引用
package com.example; public class Person{ // 父类 public String name="李四"; public int age = 18; public void speak(){ System.out.println("Person: speak()"); } public void cry(){ System.out.println("Person: cry()"); } }
package com.example; public class Man extends Person{ // 子类 public void speak(){ System.out.println("Man: speak()"); super.speak(); // 调用父类的 speak cry(); // 调用父类的 cry System.out.println("name: " + name); // 调用父类的 name System.out.println("age: " + super.age); // 调用父类的 age } public static void main(String[] args){ Man m = new Man(); m.speak(); } }
运行结果:
Man: speak() Person: speak() Person: cry() name: 李四 age: 18
- 当子类中重写了父类中的方法时,我们在new一个子类对象的时候会先产生一个父类对象,在产生子类对象。那么在调用重写的方法时候,会优先调用子类的方法,但也不是说父类中被重写的方法就没了,其实不是这样的,只是我们要调用父类中被重写的方法要用super.的方式调用。
- 上面代码中父类和子类中都有 speak 方法,所以子类中想要调用父类的 speak 方法时,必须要用 super 关键字(这种情况是子类对父类的方法进行了重写)
- 如果父类中其他方法没有被子类重写,那么在new一个子类对象的时候,子类引用可以直接引用父类中的所有方法和属性,这就是继承。
2)第二种用法:super(参数列表) 调用父类的构造器
例1:
package com.example; public class Person{ public Person(int i){ System.out.println("Person" + "(" + i + ")"); } public Person(String str){ System.out.println("Person" + "(" + str + ")"); } class Man extends Person{ public Man(){ super(1); // 调用父类构造器 System.out.println("Man()"); } public Man(int i){ super("张三"); // 调用父类构造器 System.out.println("Man" + "(" + i + ")"); } public Man(String str){ super(2); // 调用父类构造器 System.out.println("Man" + "(" + str + ")"); } }public static void main(String[] args){ Man a= new Man("张三"); } }
运行结果: Person(2) Man(张三)
- 父类构造器只能在子类构造器中调用,不能在子类的方法中调用,父类构造器只能位于子类构造器的第一行
- 如果我们没有给类创建构造器,编译器会为该类自动创建一个默认构造器(无参构造器),如果我们给类创建了构造器,那么编译器便不会再为类创建默认构造器
- 当父类中含有默认构造器时,编译器会在子类的构造器中自动调用父类的默认构造器,以完成父类的初始化。
- 当父类中含有无参构造器时,编译器也会在子类构造器中自动调用父类的无参构造器
- 当父类中只含有有参构造器时,编译器不会在子类构造器中自动调用父类的构造器,此时我们必须在子类的所有构造器中都对父类中的一个构造器进行调用,否则编译时会报错,例如:例子中子类 Man 中的每一个构造器都调用了父类的构造器
- 总结:在继承关系中,父类最好不创建构造器或者在创建多个构造器时要创建一个无参构造器,这样才不用每个子类的构造器都对父类的构造器进行调用