参考:
https://blog.csdn.net/yongbutingxide/article/details/82669054#1.super()%E7%9A%84%E4%BD%BF%E7%94%A8%E5%AE%9E%E4%BE%8B%20%E4%B8%80%E4%B8%80%E4%B8%80%E5%AD%90%E7%B1%BB%E9%87%8D%E5%86%99%E7%88%B6%E7%B1%BB%E7%9A%84%E6%96%B9%E6%B3%95
https://www.cnblogs.com/yyy6/p/8976584.html
一、用法
super是指向父类的引用,如果构造方法没有显示地调用父类的构造方法,那么编译器会自动为它加上一个默认的super()方法调用。如果父类由没有默认的无参构造方法,编译器就会报错,super()语句必须是构造方法的第一个子句。
定义子类的一个对象时,会先调用子类的构造函数,然后在调用父类的构造函数,如果父类函数足够多的话,会一直调用到最终的父类构造函数,函数调用时会使用栈空间,所以按照入栈的顺序,最先进入的是子类的构造函数,然后才是邻近的父类构造函数,最后再栈顶的是最终的父类构造函数,构造函数执行是则按照从栈顶到栈底的顺序依次执行.
现在以Bird--> Animal --> Object 为线举例说明
1 public class Animal { 2 int eye = 2; 3 public Animal(){ 4 super(); 5 System.out.println("动物"); 6 } 7 8 public void run(){ 9 System.out.println("动物有不同走路方式"); 10 } 11 12 public static void main(String[] args) { 13 Bird b = new Bird(); 14 b.run(); 15 } 16 } 17 18 class Bird extends Animal{ 19 public Bird(){ 20 super(); 21 System.out.println("鸟类"); 22 } 23 24 @Override 25 public void run() { 26 // TODO Auto-generated method stub 27 super.run(); // 通过super可以用父类方法和属性 28 System.out.println("鸟是飞飞飞飞飞飞"); 29 System.out.println("鸟类有"+super.eye+"只眼睛"); 30 } 31 32 }
结果:
动物
鸟类
动物有不同走路方式
鸟是飞飞飞飞飞飞
鸟类有2只眼睛
Bird--> Animal --> Object 图形分析如下:
更加详细的例子在下面:
1.super()的使用实例 一一一子类重写父类的方法
1 public class A { 2 3 private String nameA="A"; 4 5 public void getName() { 6 System.out.println("父类"+nameA); 7 } 8 public static void main(String[] args) { 9 } 10 11 } 12 13 14 public class B extends A{ 15 private String nameB="B"; 16 17 @Override 18 public void getName() { 19 System.out.println("子类"+nameB); 20 super.getName(); 21 } 22 23 public static void main(String[] args) { 24 B b=new B(); 25 b.getName(); 26 27 } 28 }
结果:
2.super()的使用实例 一一一子类重写父类的变量
1 public class A { 2 3 String nameA="A"; 4 5 } 6 7 public class B extends A{ 8 String nameA="B"; 9 10 11 public void getName() { 12 System.out.println("子类"+nameA); 13 System.out.println("父类"+super.nameA); 14 } 15 16 public static void main(String[] args) { 17 B b=new B(); 18 b.getName(); 19 20 } 21 }
结果:
3.super()的使用实例 一一一在子类的构造方法中
编译器会自动在子类构造函数的第一句加上 super(); 来调用父类的无参构造器;此时可以省略不写。如果想写上的话必须在子类构造函数的第一句,可以通过super来调用父类其他重载的构造方法,只要相应的把参数传过去就好。
因此,super的作用主要在下面三种情况下:
1、调用父类被子类重写的方法;
2、调用父类被子类重定义的字段(被隐藏的成员变量);
3、调用父类的构造方法;
其他情况,由于子类自动继承了父类相应属性方法,关键字super可以不显示写出来。
4.关于构造方法中super()
第一种情况:编译不通过
分析:
如果一个类中没有写任何的构造方法,JVM会生成一个默认的无参构造方法。在继承关系中,由于在子类的构造方法中,第一条语句默认为调用父类的无参构造方法(即默认为super(),一般这句话省略了)。所以当在父类中定义了有参构造函数,都是没有定义无参构造函数时,IDE会强制要求我们定义一个相同参数类型的构造器。
在本例中JVM默认给B加了一个无参构造方法,而在这个方法中默认调用了super(),但是父类中并不存在该构造方法
第二种情况:编译不通过
同样编译错误,相同的道理,虽然我们在子类中自己定义了一个构造方法,但是在这个构造方法中还是默认调用了super(),但是父类中并不存在该构造方法
第三种情况:成功编译通过
1 public class A { 2 public A(String s) { 3 4 } 5 6 } 7 8 public class B extends A{ 9 public B(String s) { 10 super(s); 11 } 12 }
分析:
所以,只要记住,在子类的构造方法中,只要里面没有显示的通过super去调用父类相应的构造方法,默认都是调用super(),即无参构造方法,因此要确保父类有相应的构造方法。
我们通过super是不能访问父类private修饰的变量和方法的,因为这个只属于父类的内部成员,一个对象是不能访问它的private成员的。