super

我们知道this的四种用法之一就是代表当前对象的引用,那么在子类继承了父类之后,在子类中使用this代表当前子类对象的引用,那怎么表示父类对象呢?在子类中又如何去使用父类的属性和方法呢?

1.super用来干什么?

super用于在子类对象中访问可继承的父类的属性和方法(包含构造方法)。

(1)访问父类的属性

语法:super.父类属性

父类:

package com.dh.oop2;

public class Parent {

    public String name = "Tom";

}

子类:访问父类属性

package com.dh.oop2;

public class Son extends Parent {

    public String name = "Jerry";

    public void show(){
        //在子类中输出父类属性
        System.out.println(super.name);
    }
}

运行类:

package com.dh.oop2;

public class SuperApplication {

    public static void main(String[] args) {

        Son son = new Son();
        son.show();
    }
}

结果:确实输出了父类的属性。

不能使用没有继承的:同一个包下,子类不能继承父类中使用private修饰的属性和方法,不能继承,更别提使用了。

(私有方法同私有属性,都不能被访问)


扩展:

super不能用于静态方法中。

与this一样,super代表的是父类对象,而static是随着类加载而初始化的,那个时候还不确定父类对象,所以不能在static中使用super。

(2)访问父类的方法

语法:super.父类方法;

父类:

package com.dh.oop2;

public class Parent {

    public String name = "Tom";

    public void parent(){
        System.out.println("我是爸爸");
    }
}

子类:

package com.dh.oop2;

public class Son extends Parent {

    public String name = "Jerry";

    public void show(){
        //在子类中使用父类属性
        System.out.println(super.name);

        //在子类中调用父类方法
       super.parent();
    }
}

运行类:

package com.dh.oop2;

public class SuperApplication {

    public static void main(String[] args) {

        Son son = new Son();
        son.show();
    }
}

结果:确实执行了父类方法。

(3)调用父类构造方法

语法:super([参数...]);

首先需要明确一点,当自己在子类的构造方法中不写super([参数]...)时,子类的构造方法中的第一行会默认的使用super()

  • 当父类不书写构造方法时,只有系统默认的无参构造方法,此时在子类中书写构造方法,并且调用父类的构造方法:

    可以看到,super()和this()一样,必须在构造方法中的第一行,所以super()和this()不能同时存在,因为两个都是要在第一行的第一个执行语句。(把两个并排放在第一行是没有用的!)

  • 当父类中书写无参构造方法:

    package com.dh.oop2;
    
    public class Parent {
    
        public String name = "Tom";
    
        //父类无参构造
        public Parent() {
            System.out.println("父类的构造方法");
        }
    }
    
    

    子类:

    package com.dh.oop2;
    
    public class Son extends Parent {
    
        public String name = "Jerry";
    
        public Son() {
            //在子类中调用父类无参构造方法
            super();
            System.out.println("子类构造方法");
        }
    }
    

    运行类:

    package com.dh.oop2;
    
    public class SuperApplication {
    
        public static void main(String[] args) {
    		//new子类对象
            Son son = new Son();
        }
    }
    
    

    结果:

    我们在继承中提到过,子类不会继承父类的构造方法,但是会调用父类的构造方法,就是在子类构造方法中使用了super(),但是我们当时没有书写也是可以的,所以,子类使用super()调用父类的无参构造方法,并且super()可以省略。

  • 当父类中只有有参构造方法:

    可以看到报错了,并且提示说需要创建一个匹配父类的构造方法。

    这是因为当子类没有书写构造方法时,系统会默认提供一个无参构造方法,并且在子类的无参构造方法中会默认的去调用父类的无参构造方法,但是父类中书写了有参构造方法,已经不存在了无参构造方法,所以自然会报错

    此时有两种解决方案:

    • 第一种:在父类中手动书写一个无参构造方法,此时子类中系统默认的无参构造方法中的super()就能成功调用父类的无参构造方法,就不会报错了。

    • 第二种:在子类中书写一个构造方法,在第一行调用父类的有参构造方法。(此时系统不再给子类提供默认的无参构造方法,但是还是会在子类的有参构造方法的第一行默认去调用父类的无参构造方法,但是父类不存在无参构造方法,所以在子类构造方法中书写有参调用,显式的去调用子类的有参构造方法,此时系统就不会去调用父类的无参构造了)。

总结:

  • super不能出现在static方法中;

  • super.父类属性,使用父类属性;

  • super.父类方法,调用父类的方法;

  • super([参数]...),调用父类的构造方法。

    • 该语句必须放在子类构造方法的第一行;

    • 与this([参数])不能同时出现;

    • 当在子类的构造方法中不书写时super([参数]...),默认会super();

    • 父类中书写了有参构造,要么给父类再写一个无参构造,

      ​ 要么给子类写一个构造方法,并在第一行调用父类的有参构造;


本人水平有限,若有错误,望指出~

posted @ 2021-01-21 11:00  deng-hui  阅读(126)  评论(0编辑  收藏  举报