首页 > 编程笔记 > Java笔记 阅读:15

Java中的super关键字(3种用法,附带实例)

super 的意思是超级的,它是 Java 的关键字之一,用于引用父类对象,通过它可以访问父类的属性和方法。

super 关键字的作用主要有以下三种,我们将对每种作用进行讲解:
  1. 调用父类的构造方法;
  2. 访问父类实例的变量;
  3. 调用父类的方法。

Java super调用父类的构造方法

观察下面的实例程序,我们定义了一个 Human 类作为父类,它包含了 name 和 age 两个属性,同时定义了两个构造方法。然后定义了一个继承 Human 类的 Man 子类,该类增加了一个 hasGirlfriend 属性,接着注意其中的两个构造方法,第一个是直接通过 super() 调用了父类的 Human() 构造方法,第二个则是通过 super(name, age) 调用了父类的另一个构造方法。
class Human {
    String name;
    int age;

    Human() {
        System.out.println("Human() 被调用");
    }

    Human(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Human(String name,int age) 被调用");
    }
}

class Man extends Human {
    boolean hasGirlfriend;

    Man() {
        super();
    }

    Man(String name, int age, boolean hasGirlfriend) {
        super(name, age);
        this.hasGirlfriend = hasGirlfriend;
    }

    public static void main(String[] args) {
        Man man = new Man();
        Man xiaoming = new Man("小明", 18, true);
    }
}
输出结果为:

Human() 被调用
Human(String name,int age) 被调用


需要注意的是,在子类构造方法中通过 super 调用父类构造方法时必须将其作为首条语句,比如下面实例中的 super(name, age) 不是首条语句,将会导致编译时报错。
Man(String name, int age, boolean hasGirlfriend) {
    this.hasGirlfriend = hasGirlfriend;
    super(name, age);
}

Java super访问父类实例的变量

下面实例中,我们在 Man 类中添加一个 introduceMyself() 方法,注意在这个方法中我们使用了“super.name”和“super.age”,其实就是通过 super 来访问父类实例的变量,因为父类才有 name 和 age 属性。
class Man extends Human {
    ......
    void introduceMyself() {
        System.out.println("my name is " + super.name + ", " + super.age + " years old.");
    }

    public static void main(String[] args) {
        Man xiaoming = new Man("小明", 18, true);
        xiaoming.introduceMyself();
    }
}
输出结果为:

Human(String name,int age) 被调用
my name is 小明, 18 years old.

Java super调用父类的方法

接下来我们继续对程序进行改造,在 Human 类中添加 eat() 方法,然后在 Man 类中添加 date() 方法,约会时会吃东西,所以就可以通过“super.eat()”来调用父类的 eat() 方法,代码如下:
class Human {
    ......
    void eat() {
        System.out.println("吃东西");
    }
}

class Man extends Human {
    ......
    void date() {
        System.out.println("约会");
        super.eat();
    }

    public static void main(String[] args) {
        Man xiaoming = new Man("小明", 18, true);
        xiaoming.date();
    }
}

Java自动添加super()

最后我们来看一个比较神奇的现象,执行如下的实例代码:
class A {
    A() {
      System.out.println("A类构造方法");
    }

    public static void main(String[] args) {
     C c = new C();
    }
}

class B extends A {
    B() {
        System.out.println("B类构造方法");
    }
}

class C extends B {
    C() {
        System.out.println("C类构造方法");
    }
}
会发现“A类构造方法”“B类构造方法”和“C类构造方法”都输出了。造成这种现象的原因是编译器会在编译时自动在子类的构造方法中添加“super();”,如下图所示,从而导致一级级往上调用,也就有了如上的输出结果。


图 1 编译时自动添加super()

相关文章