指向父类的引用——super

参考:

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成员的。

猜你喜欢

转载自www.cnblogs.com/qiaoxin11/p/12543715.html