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关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java实现简单注册选择所在城市

    java实现简单注册选择所在城市

    这篇文章主要为大家详细介绍了java实现简单注册选择所在城市的相关代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • Java中BigDecimal除法使用不当导致精度问题

    Java中BigDecimal除法使用不当导致精度问题

    本文主要介绍了Java中BigDecimal除法使用不当导致精度问题,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Springboot实现邮箱验证码注册与修改密码及登录功能详解流程

    Springboot实现邮箱验证码注册与修改密码及登录功能详解流程

    验证码作为一种自然人的机器人的判别工具,被广泛的用于各种防止程序做自动化的场景中。传统的字符型验证安全性已经名存实亡的情况下,各种新型的验证码如雨后春笋般涌现,今天给大家分享一篇SpringBoot实现滑块验证码
    2022-11-11
  • java 爬虫详解及简单实例

    java 爬虫详解及简单实例

    这篇文章主要介绍了java 爬虫详解及简单实例的相关资料,需要的朋友可以参考下
    2017-05-05
  • java必学必会之线程(2)

    java必学必会之线程(2)

    本文对java线程进行深入学习,重点介绍了线程同步问题、线程死锁问题,感兴趣的小伙伴们可以参考一下
    2015-12-12
  • SpringBoot AOP控制Redis自动缓存和更新的示例

    SpringBoot AOP控制Redis自动缓存和更新的示例

    今天小编就为大家分享一篇关于SpringBoot AOP控制Redis自动缓存和更新的示例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • 使用JavaSE来模拟斗地主

    使用JavaSE来模拟斗地主

    这篇文章主要介绍了使用JavaSE来模拟斗地主,对棋牌游戏有研究的同学可以参考一下
    2021-04-04
  • Java实现“年-月-日 上午/下午时:分:秒”的简单代码

    Java实现“年-月-日 上午/下午时:分:秒”的简单代码

    当前的日期输出的方法有很多,本文为大家介绍下在java中是如何实现“年-月-日 上午/下午时:分:秒”,感兴趣的朋友不妨参考下
    2015-08-08
  • JavaSE实现图书管理系统的示例代码

    JavaSE实现图书管理系统的示例代码

    这篇博客是在学习了一部分Java基础语法之后的练习项目,通过这个小项目的练习,对Java中的类和对象,抽象类和接口等进行熟悉理解。快跟随小编一起学习学习吧
    2022-08-08
  • Java中分割字符串的两种方法实例详解

    Java中分割字符串的两种方法实例详解

    这篇文章主要介绍了Java中分割字符串的两种方法,一种是java.lang.String 的 split() 方法,,另外一种是用String Tokenizer类。文中的每种方法都给出了详细的示例代码,相信对大家的理解和学习具有一定的参考借鉴价值,有需要的朋友们下面来一起看看吧。
    2016-12-12

最新评论