ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

【Java】super关键字详解

【Java】super关键字详解

文章目录

    • 一、super 关键字
      • 1.1 super 是什么
      • 1.2 super 访问父类成员变量
      • 1.3 super 调用父类成员方法
      • 1.4 super 调用父类构造方法
      • 1.5 super 注意事项
    • 二、super 与 this 的区别
      • 2.1 概念对比
      • 2.2 调用构造方法的区别
    • 三、综合示例代码

一、super 关键字

1.1 super 是什么

super作用:在子类方法中访问父类成员

  • 访问父类的成员变量
  • 调用父类的成员方法
  • 调用父类的构造方法

1.2 super 访问父类成员变量

当子类定义了与父类同名的成员变量时,此时可以通过super.变量名来访问父类的变量。

publicclassAnimal{Stringname="动物";}publicclassDogextendsAnimal{Stringname="狗";publicvoidshow(){System.out.println("子类 name = "+name);// 输出:狗System.out.println("父类 name = "+super.name);// 输出:动物}}

1.3 super 调用父类成员方法

当子类重写(@Override)父类的方法后,如果还想调用父类被重写的方法,可以使用super.方法名()。

classAnimal{publicvoideat(){System.out.println("动物在吃东西");}}classDogextendsAnimal{@Overridepublicvoideat(){super.eat();// 先调用父类的方法System.out.println("狗在啃骨头");}}

1.4 super 调用父类构造方法

super(参数列表)用于在子类构造方法中显式调用父类的构造方法。
必须放在子类构造方法的第一行。

classAnimal{publicAnimal(Stringname){System.out.println("父类构造方法:"+name);}}classDogextendsAnimal{publicDog(Stringname){super(name);// 必须第一行System.out.println("子类构造方法");}}

1.5 super 注意事项

  • super不能出现在静态方法中,因为静态方法属于类,不依赖对象实例。
  • super不能用于访问父类的私有成员(private修饰的变量和方法)。
  • 如果父类没有无参构造方法,子类构造方法必须显式调用super(参数),否则编译报错。

二、super 与 this 的区别

2.1 概念对比

对比superthis
含义引用父类对象引用当前对象
访问成员变量super.变量名访问父类成员this.变量名访问本类成员
调用成员方法super.方法名()调用父类方法this.方法名()调用本类方法
调用构造方法super(参数)调用父类构造方法this(参数)调用本类其他构造方法
使用位置子类中本类中
静态方法中使用不允许不允许

2.2 调用构造方法的区别

  • this(参数):调用本类的其他构造方法。
  • super(参数):调用父类的构造方法。

两者都必须放在构造方法的第一行,因此不能同时出现。

classPerson{publicPerson(){System.out.println("父类无参构造");}publicPerson(Stringname){System.out.println("父类有参构造:"+name);}}classStudentextendsPerson{publicStudent(){this("张三");// 调用本类有参构造System.out.println("子类无参构造");}publicStudent(Stringname){super(name);// 调用父类有参构造System.out.println("子类有参构造");}}

三、综合示例代码

下面通过一个综合示例,把 super 和 this 结合起来:

classBase{publicBase(){System.out.println("Base 构造方法");}publicBase(Stringmsg){System.out.println("Base 有参构造:"+msg);}}classDerivedextendsBase{publicDerived(){this("默认");System.out.println("Derived 无参构造");}publicDerived(Stringmsg){super(msg);System.out.println("Derived 有参构造:"+msg);}}publicclassMain{publicstaticvoidmain(String[]args){newDerived();}}

输出结果:

Base 有参构造:默认 Derived 有参构造:默认 Derived 无参构造

new Derived()触发子类无参构造Derived()

  1. Derived()第一行:this("默认")→ 调用本类Derived("默认")
  2. 进入Derived(String msg),第一行super(msg)→ 调用父类Base("默认")
  3. 执行父类有参构造:打印Base 有参构造:默认
  4. 回到子类有参构造,继续往下执行:打印Derived 有参构造:默认
  5. 回到子类无参构造,执行this("默认")后面代码:打印Derived 无参构造
返回列表