Java中super关键字的用法和细节

 更新时间:2022年01月16日 08:57:51   作者:今天上传git了吗  
大家好,本篇文章主要讲的是Java中super关键字的用法和细节,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下

前言

    因为西安疫情的原因在宿舍摆了一个月,最近在复习前面学过的知识的时候发现,自己在初学面向对象时对Super关键字的理解不够深刻,所以现在重新学习一下super关键字的用法和细节。

 1. super关键字的用法

    在Java中,super关键字共有三种用法,分别是:

通过 super.属性名 来访问父类中的成员变量

通过super.方法名(参数列表) 来访问父类中的成员方法

通过super(参数列表) 来访问父类的构造方法

调用父类的成员变量:

class Person {
    protected int age;
}
class Student extends Person{
    public void func(){
        int age = super.age;	//通过super.属性名访问父类的成员变量
    }
}
调用父类中的成员方法:
class Person {
    protected void func(){
        
    }
}
class Student extends Person{
    public void func(){
        super.func();	//通过super.方法名调用父类的成员方法
    }
}
调用父类的构造器:
class Person {
    String name;
    public Person(String name) {
        this.name = name;
    }
}
class Student extends Person{
    public Student(String name) {
        super(name);	//通过super(参数列表)调用父类的构造方法
    }
    
}
注意:

子类无法通过super关键字访问父类中private修饰的属性和方法,因为private修饰的属性和方法只能在当前类的内部进行访问在子类的构造器中通过super关键字调用父类的构造器时,super关键字必须出现在构造器的第一行且仅能出现一次

2. super关键字的使用细节

当我们查找子类中的方法时,调用规则如下:

当子类中存在需要调用的方法时,直接调用即可如果子类中不存在该方法,则向上寻找父类,如果父类中存在该方法,则调用父类中的方法若父类中不存在该方法,那么向上寻找父类的父类,直到找到Object类

提示:如果直到Object类依然没有找到该方法,那么会提示方法不存在,但如果向上找到了这个方法但没有权限访问(例如该方法被private修饰),则会产生错误。

public class Test extends Test2{
    public static void main(String[] args) {
        Test test = new Test();
        test.func1();	
    }
    public void func1(){
        System.out.println("子类中的func1()");
        func2();
    }
}
class Test2{
    public void func2(){
        System.out.println("父类中的func2()");
    }
}
//结果:
子类中的func1()
父类中的func2()

    在上述代码中,子类中的func1()方法在调用func2()方法时会在子类中查找是否存在func2()方法,未找到时会在其父类中查找func2()方法。

    当我们将func1()中的语句 func2(); 改为 this.func2(); 此时语义未发生改变,依然会先在子类中查找,没有找到时会在其父类中查找。

    当我们再将 this.func2(); 改为 super.func2(); 这时语义就发生了变化,上面提到过,super.方法名()调用的是父类中的方法,那么这条语句就不会检测当前类中是否存在func2()方法,只会在其父类中依次向上进行检测。例如:

public class Test extends Test2{
    public static void main(String[] args) {
        Test test = new Test();
        test.func1();
    }
    public void func1(){
        System.out.println("子类中的func1()");
        super.func2();	//这里编译无法通过
    }
    public void func2(){
        System.out.println("字类中的func2()");
    }
}
class Test2{
    public void func3(){
        System.out.println("父类中的func3()");
    }
}
//编译未通过,提示无法解析Test2中的方法func2()

注:成员属性与成员方法同理。

    我们已经知道了,super关键字的访问并不仅仅局限于父类,即使是父类的父类,父类的父类的父类,甚至再往上,都可以通过super关键字访问到。那么,如果子类上面的多个类中都存在同样的成员,此时使用super关键字访问的是哪个类中的成员呢?

    当子类要访问上级类的某个成员,而子类的多个上级类都有该成员时,我们对super关键字的使用采用就近原则,也就是访问super关键字向上找到的第一个成员。例如:

public class Test extends Test2{
    public static void main(String[] args) {
        Test test = new Test();
        test.func1();
    }
    public void func1(){
        System.out.println("子类中的func1()");
        super.func2();	//子类通过super关键字访问上级类中的func2()
    }
}
class Test2 extends Test3{
    public void func2(){
        System.out.println("父类中的func2()");
    }
}
class Test3{
    public void func2(){
        System.out.println("父类的父类中的func2()");
    }
}
//结果:
子类中的func1()
父类中的func2()

    在上述代码中,子类通过super关键字访问上级类中的func2()方法,子类继承Test2,Test2继承Test3,此时Test2和Test3中都存在func2(),此时子类先访问其父类Test2,Test2中存在func2()方法,那么直接访问Test2中的func2()即可,若Test2中不存在func2(),则super关键字会继续向上访问。

3. super和this关键字的比较

    下面这个表格列出了super关键字和this关键字的区别:

请添加图片描述

总结

到此这篇关于Java中super关键字的用法和细节的文章就介绍到这了,更多相关Java super关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot 项目启动自动执行方法的两种实现方式

    Spring Boot 项目启动自动执行方法的两种实现方式

    这篇文章主要介绍了Spring Boot 项目启动自动执行方法的两种实现方式,帮助大家更好的理解和学习使用Spring Boot框架,感兴趣的朋友可以了解下
    2021-05-05
  • Java实现自定义LinkedList类的示例代码

    Java实现自定义LinkedList类的示例代码

    LinkedList类跟ArrayList类不同,它通过指针以及结点的操作对链表进行增删改查。本文就来和大家分享下Java如何为实现自定义LinkedList类,需要的可以参考一下
    2022-08-08
  • 在Java中操作Zookeeper的示例代码详解

    在Java中操作Zookeeper的示例代码详解

    这篇文章主要介绍了在Java中操作Zookeeper的示例代码详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Java实现局域网IP地址扫描

    Java实现局域网IP地址扫描

    这篇文章主要为大家详细介绍了Java实现局域网IP地址扫描,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • springboot 集成redis哨兵主从的实现

    springboot 集成redis哨兵主从的实现

    本文主要介绍了springboot 集成redis哨兵主从的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • mybatis多层嵌套resultMap及返回自定义参数详解

    mybatis多层嵌套resultMap及返回自定义参数详解

    这篇文章主要介绍了mybatis多层嵌套resultMap及返回自定义参数详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • Java实现差分数组的示例详解

    Java实现差分数组的示例详解

    差分数组是由原数组进化而来,值为原数组当前位置值减去上一个位置的值。本文将通过例题详解如何利用Java实现差分数组,需要的可以参考一下
    2022-06-06
  • Flowable数据库表分类及数据字典解析

    Flowable数据库表分类及数据字典解析

    这篇文章主要介绍了Flowable数据库表分类及数据字典解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Java 文件解压缩实现代码

    Java 文件解压缩实现代码

    这篇文章主要介绍了Java 文件解压缩实现代码,有需要的朋友可以参考一下
    2013-12-12
  • Java数据封装树形结构代码实例

    Java数据封装树形结构代码实例

    这篇文章主要介绍了Java数据封装树形结构代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01

最新评论