Java中Super的用法详解

Java中的super关键字,就如字面意思,代表的就是超类(父类)。与之相对应的关键字就是this,就就是当前类。应用到操作的对象来说,分别代表的就是父类对象和当前类对象。

一、Super在方法和属性中的应用:

当父类,子类同时出现相同属性名却带有不同修饰符的属性时,thissuper 就能很好的区分对象要调用的是哪个对象的属性。如:

父类,子类中都有属性name,this,super就把调用很好的区分开来
//父类:
public String name = "动物";
//子类:
private String name = "小鸟";
//子类对象中调用结果:
this.name ==> 小鸟
super.name ==> 动物

1. 实例:

三文件,Application.java,Animal.java(父类),Bird.java(子类)
//Application.java
package com.zctou.oop;


import com.zctou.oop.demo05.Bird;

public class Application {

    public static void main(String[] args) {
        Bird bird = new Bird();
        bird.fly("麻雀");
        bird.eat("cat");

    }
}


//Animal.java
package com.zctou.oop.demo05;

public class Animal {
    public String name = "动物"; //animal's name
    Boolean hasLegs = true; // true or false
    protected  String bodySize = "normal"; //huge, normal or small
    private int eyesNum = 2; // exist eyes

    protected void eat() {
        System.out.println(name + "开吃了!");
    }
}


//Bird.java
package com.zctou.oop.demo05;

public class Bird extends Animal{
    public String name = "小鸟"; //与父类同属性名,同修饰符
    private  String bodySize = "small";

    public void fly(String name) {
        System.out.println(name);
        System.out.println(this.name);
        System.out.println("调用父类方法: " + super.name + "起飞了!");

    }

    public void eat(String name) {
        System.out.print("利用super关键字调用父类方法:"); 
        super.eat(); //父对象 eat()方法的修饰符为 protected
        System.out.print("不带super关键字调用父类方法:");
        eat();
    }

}

输出:

麻雀
小鸟
调用父类方法: 动物起飞了!

2. 总结:

  1. 父类的非私有方法和属性都可以被继承。使用在子对象中用 super关键字都能调用。私有方法和属性无法被子类调用
  2. 子类与父类可以有相同的属性名和方法名,且同修饰符。
  3. 便于区分及代码的可读性,用thissuper区分不同对象的属性及方法。

二、 Super在构造器中的应用 :

前面已经了解【过this关键字在构造器中的应用】,这里再扩展一下super关键字在构造器中的用法。

  1. 生成子类对象时,先调用父类无参构造,后调用子类无参构造

    //Application.java
    package com.zctou.oop;
    
    
    import com.zctou.oop.demo05.Fish;
    
    public class Application {
    
        public static void main(String[] args) {
            Fish fish = new Fish(); 
        }
    }
    
    // Animal.java
    package com.zctou.oop.demo05;
    
    public class Animal {
        public Animal() {
            System.out.println("Animal类(父类)无参构造被调用!");
        }
    }
    
    //Fish.java
    package com.zctou.oop.demo05;
    
    public class Fish extends Animal {
        public Fish() {
            System.out.println("Fish类(子类)无参构造被调用!");
    
        }
        private String name = "大鱼";
    
    }
    //输出:
    Animal类(父类)无参构造被调用!
    Fish类(子类)无参构造被调用!
    可以看到new Fish()的时候,先调用的是父类Animal的无参构造,再调用子类Fish的无参构造。
  2. 如果没有显式定义,在子类无参构造中,系统也会默认加上super()调用父类无参构造:

    如在Fish.java的无参构造中加入显式定义:

    package com.zctou.oop.demo05;
    
    public class Fish extends Animal {
        public Fish() {
            super(); //加入显式定义:
            System.out.println("Fish类(子类)无参构造被调用!");
    
        }
    }
    
    //输出:
    Animal类(父类)无参构造被调用!
    Fish类(子类)无参构造被调用!
    手动加显示定义super()的输出结果跟没加上super()的样,因为系统默认就加上父类的无参构造调用语句super();
  3. this一样,super同样要放在第一行,且构造中this()super()不能同时存在。如在Fish.java中同时加入this与super:

    package com.zctou.oop.demo05;
    
    public class Fish extends Animal {
        public Fish() {
            this(); //this(),super()同时存在
            super();
            System.out.println("Fish类(子类)无参构造被调用!");
        }
    
    }
    //输出:
    java: 对super的调用必须是构造器中的第一个语句
    
    可以看到,运行结果报错,提示super调用要第一个语句。IDEA编辑时报的错误为 “Call to 'super()' must be first statement in constructor body”。
  4. 父类定义了有参构造而没有显式定义无参时,子类同样无法定义无参构造,也无法调用父类无参。如Animal.java中只定义有参构造,子类定义无参时会报错。

    // Animal.java 只定义无参,没有显式定义无参构造
    package com.zctou.oop.demo05;
    
    public class Animal {
        public Animal(String s) {
            System.out.println("Animal类(父类)无参构造被调用!");
        }
    }

    报错信息:父类中无法找到默认的构造器

    Java面向对象编程10 - Super详解

    子类调用父类无参super()同样的错误提示:

    Java面向对象编程10 - Super详解

三、小结

Super 与 This 的几个主要区别

  1. super 与 this 指代的对象:

    super 指向的是子对象对父类对象的引用,而this批向的是自己(即调用的这个对象)。
  2. 使用条件的区别:

    this不需要继承关系,super只能出现在继承关系的子类中。
  3. 在构造方法中的区别:

    this是本类构造,super是父类构造。
    都不显式定义的情况下,子类默认调用父类无参构造super()。
  4. 在构造方法中,super和this都要写第一行,因此两者只能同时在于一个。
文章目录