Java学习笔记之深入理解关键字super

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GongchuangSu/article/details/51920688

为什么需要super

考虑这样一个情景,当一个类继承自另一个类,并重写了父类的一个方法,并且想在这个方法中调用父类的这个方法,该如何做呢?当然,我们不能直接调用该方法,因为它会产生递归。这时,我们就需要通过super.方法名来访问父类的该方法。
当然,super的存在不仅仅如此。我们知道,当创建一个导出类(即通过继承而来)的对象时,该对象会包含一个基类的子对象。这就需要我们正确的对基类子对象进行初始化。如何正确的基类子对象进行初始化呢?这时,super就派上用场了。当基类构造器不带有参数,Java会自动在导出类的构造器中插入对基类构造器的调用(即隐式的使用了super()),而不需手动编写。但如果基类构造器是带有参数的,那就必须得手动编写,显式的插入带有相应参数的super(参数列表)方法,而且,值得注意的是,必须将该方法放在导出类构造器的第一行。
super还有另外一个用处,就是可以通过它来访问基类中被隐藏的成员变量(即被子类覆盖的成员变量,非private成员变量),引用格式:super.成员变量名

如何使用super

package com.gongchuangsu.reusing;

class Animal{
    public String s1 = "str_1 in Animal";
    public String s2 = "str_2 in Animal";

    public Animal(int i) {
        System.out.println("Animal");
    }

    public void f(){ 
        System.out.println("Animal say...");
    }
}

class Dog extends Animal{
    public String s1 = "str_1 in Dog";
    public String s2 = "str_2 in Dog";

    public Dog(int i) {
        super(i);
        System.out.println("Dog");
    }

    public void f(){ 
        System.out.println("Dog say...");
    }
}

public class Teddy extends Dog{
    public String s1 = "str_1 in Teddy";

    public Teddy(int i) {
        super(i);  // 调用父类带参构造函数完成父类初始化,其必须放在第一行
        System.out.println("Teddy");
    }

    public void f(){ 
        System.out.println(s1);             // 访问所在类的成员变量
        System.out.println(s2);             // 访问父类的成员变量
        System.out.println(super.s1);       // 访问父类被隐藏的成员变量,即被子类覆盖的成员变量
        System.out.println("Teddy say...");
    }

    public static void main(String[] args){
        Teddy teddy = new Teddy(0);
        teddy.f();  
    }
}
/*output
Animal
Dog
Teddy
str_1 in Teddy
str_2 in Dog
str_1 in Dog
Teddy say...
*/

参考资料

  1. Java编程思想

猜你喜欢

转载自blog.csdn.net/GongchuangSu/article/details/51920688