说一说 this 和 super 有什么区别?this 能调用到父类吗?

简介: 我是小假 期待与你的下一次相遇 ~

 1、super 关键字

super 是用来访问父类实例属性和方法的。

1.1 super 方法使用

每个实例类如果没有显示的指定构造方法,那么它会生成一个隐藏的无参构造方法。对于 super() 方法也是类似,如果没有显示指定 super() 方法,那么子类会生成一个隐藏的 super() 方法,用来调用父类的无参构造方法,这就是开篇所说的“每个类在实例化的时候之所以能调用到 Object 类,就是默认 super 方法起作用了”,接下来通过实例来验证一下这个说法。

PS:所谓的“显示”,是指在程序中主动的调用,也就是在程序中添加相应的执行代码。

public class SuperExample {
    // 测试方法
    public static void main(String[] args) {
        Son son = new Son();
    }
}
/**
 * 父类
 */
class Father {
    public Father() {
        System.out.println("执行父类的构造方法");
    }
}
/**
 * 子类
 */
class Son extends Father {
}

image.gif

在以上代码中,子类 Son 并没有显示指定 super() 方法,运行以上程序,执行的结果如下:

image.gif 编辑

从上述的打印结果可以看出,子类 Son 在没有显示指定 super() 方法的情况下,竟然调用了父类的无参构造方法,这样从侧面验证了,如果子类没有显示指定 super() 方法,那么它也会生成一个隐藏的 super() 方法。这一点也可以从此类生成的字节码文件中得到证实,如下图所示:

image.gif 编辑

super 方法注意事项

如果显示使用 super() 方法,那么 super() 方法必须放在构造方法的首行,否则编译器会报错,如下代码所示:

image.gif 编辑

如上图看到的那样,如果 super() 方法没有放在首行,那么编译器就会报错:提示 super() 方法必须放到构造方法的首行。为什么要把 super() 方法放在首行呢?这是因为,只要将 super() 方法放在首行,那么在实例化子类时才能确保父类已经被先初始化了。

1.2 super 属性使用

使用 super 还可以调用父类的属性,比如以下代码可以通过子类 Son 调用父类中的 age 属性,实现代码如下:

public class SuperExample {
    // 测试方法
    public static void main(String[] args) {
        Son son = new Son();
    }
}
/**
 * 父类
 */
class Father {
    // 定义一个 age 属性
    public int age = 30;
    public Father() {
        super();
        System.out.println("执行父类的构造方法");
    }
}
/**
 * 子类
 */
class Son extends Father {
    public Son() {
        System.out.println("父类 age:" + super.age);
    }
}

image.gif

以上程序的执行结果如下图所示,在子类中成功地获取到了父类中的 age 属性:

image.gif 编辑

2、this 关键字

this 是用来访问本类实例属性和方法的,它会先从本类中找,如果本类中找不到则在父类中找。

2.1 this 属性使用

this 最常见的用法是用来赋值本类属性的,比如常见的 setter 方法,如下代码所示:

image.gif 编辑

上述代码中 this.name 表示 Person 类的 name 属性,此处的 this 关键字不能省略,如果省略就相当于给当前的局部变量 name 赋值 name,自己给自己赋值了。可以尝试一下,将 this 关键字取消掉,实现代码如下:

class Person {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}
public class ThisExample {
    public static void main(String[] args) {
        Person p = new Person();
        p.setName("Fcant");
        System.out.println(p.getName());
    }
}

image.gif

以上程序的执行结果如下图所示:

image.gif 编辑

从上述结果可以看出,将 this 关键字去掉之后,赋值失败,Person 对象中的 name 属性就为 null 了。

2.2 this 方法使用

可以使用 this() 方法来调用本类中的构造方法,具体实现代码如下:

public class ThisExample {
    // 测试方法
    public static void main(String[] args) {
        Son p = new Son("Java");
    }
}
/**
 * 父类
 */
class Father {
    public Father() {
        System.out.println("执行父类的构造方法");
    }
}
/**
 * 子类
 */
class Son extends Father {
    public Son() {
        System.out.println("子类中的无参构造方法");
    }
    public Son(String name) {
        // 使用 this 调用本类中无参的构造方法
        this();
        System.out.println("子类有参构造方法,name:" + name);
    }
}

image.gif

以上程序的执行结果如下图所示:

image.gif 编辑

从上述结果中可以看出,通过 this() 方法成功调用到了本类中的无参构造方法。 :::tips 注意:this() 方法和 super() 方法的使用规则一样,如果显示的调用,只能放在方法的首行。 :::

2.3 this 访问父类方法

接下来,尝试使用 this 访问父类方法,具体实现代码如下:

public class ThisExample {
    public static void main(String[] args) {
        Son son = new Son();
        son.sm();
    }
}
/**
 * 父类
 */
class Father {
    public void fm() {
        System.out.println("调用了父类中的 fm() 方法");
    }
}
/**
 * 子类
 */
class Son extends Father {
    public void sm() {
        System.out.println("调用子类的 sm() 方法访问父类方法");
        // 调用父类中的方法
        this.fm();
    }
}

image.gif

以上程序的执行结果如下:

image.gif 编辑

从上述结果可以看出,使用 this 是可以访问到父类中的方法的,this 会先从本类中找,如果找不到则会去父类中找。

3、thissuper 的区别

1.指代的对象不同

super 指代的是父类,是用来访问父类的;而 this 指代的是当前类。

2.查找范围不同

super 只能查找父类,而 this 会先从本类中找,如果找不到则会去父类中找。

3.本类属性赋值不同

this 可以用来为本类的实例属性赋值,而 super 则不能实现此功能。

4.this 可用于 synchronized

因为 this 表示当前对象,所以this 可用于 synchronized(this){....} 加锁,而 super 则不能实现此功能。

总结

thissuper 都是 Java 中的关键字,都起指代作用,当显示使用它们时,都需要将它们放在方法的首行(否则编译器会报错)。this 表示当前对象,super 用来指代父类对象,它们有四点不同:指代对象、查找访问、本类属性赋值和 synchronized 的使用不同。

如果小假的内容对你有帮助,请点赞评论收藏。创作不易,大家的支持就是我坚持下去的动力!

image.gif 编辑

相关文章
HarmonyOS NEXT仓颉开发语言实战案例:电影App
周末好!本文分享使用仓颉语言重构ArkTS实现的电影App案例,对比两者在UI布局、组件写法及语法差异。内容包括页面结构、列表分组、分类切换与电影展示等。通过代码演示仓颉在HarmonyOS开发中的应用。##仓颉##ArkTS##HarmonyOS开发
|
7月前
|
JSON Java 数据库连接
IDEA的插件大总汇 (让你的工作效率大大提高!)
我是小假 期待与你的下一次相遇 ~
1876 5
|
存储 关系型数据库 MySQL
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
最全MySQL面试60题(含答案):存储引擎+数据库锁+索引+SQL优化等
2131 0
|
7月前
|
人工智能 开发者
2025魔搭开发者大会!来了!
2025魔搭开发者大会!来了!
1015 1
|
7月前
|
存储 算法 Java
JvM JDK JRE 三者区别与联系详解
本文深入解析了Java编程中的三个核心概念:JVM(Java虚拟机)、JDK(Java开发工具包)和JRE(Java运行环境)。JVM是执行Java字节码的虚拟计算机,实现“一次编译,到处运行”;JDK包含JRE及开发工具,用于编写和调试Java程序;JRE负责运行已编译的Java程序。文章详细阐述了它们的功能、组成及应用场景,并通过实例说明其在实际开发中的作用,帮助开发者理解三者联系与区别,提升开发效率与问题解决能力。适合Java初学者及进阶开发者学习参考。
1134 3
|
12月前
|
IDE 测试技术 项目管理
【新手必看】PyCharm2025 免费下载安装配置教程+Python环境搭建、图文并茂全副武装学起来才嗖嗖的快,绝对最详细!
PyCharm是由JetBrains开发的Python集成开发环境(IDE),专为Python开发者设计,支持Web开发、调试、语法高亮、项目管理、代码跳转、智能提示、自动完成、单元测试和版本控制等功能。它有专业版、教育版和社区版三个版本,其中社区版免费且适合个人和小型团队使用,包含基本的Python开发功能。安装PyCharm前需先安装Python解释器,并配置环境变量。通过简单的步骤即可在PyCharm中创建并运行Python项目,如输出“Hello World”。
4232 13
【新手必看】PyCharm2025 免费下载安装配置教程+Python环境搭建、图文并茂全副武装学起来才嗖嗖的快,绝对最详细!
|
12月前
|
SQL Java 数据库连接
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
673 29
|
9月前
|
安全 Java 开发者
Java 泛型中的通配符 T,E,K,V,?有去搞清楚吗?
本文介绍了Java泛型及其通配符的使用方法与作用。泛型是JDK5引入的特性,提供编译时类型安全检测,避免运行时类型转换异常。文中详细解析了常见通配符T、E、K、V、?的含义及应用场景,如无界通配符`<?>`、上界通配符`<? extends T>`和下界通配符`<? super T>`。通过代码示例,展示了泛型在类型安全、消除强制转换、代码复用和增强可读性等方面的优势。最后强调深入理解技术原理的重要性,以提升开发能力。
392 0
|
10月前
|
存储 JSON NoSQL
微服务——MongoDB的数据模型
MongoDB采用文档(document)作为最小存储单位,类似关系型数据库中的行,使用BSON(Binary-JSON)格式存储数据。BSON是JSON的二进制扩展,支持内嵌文档和数组,新增了如Date、BinData等特殊数据类型,具有轻量、高效、可遍历的特点,适合非结构化与结构化数据存储。其灵活性高,但空间利用率略低。BSON数据类型包括string、integer、boolean等基本类型及date、object id等扩展类型。
267 0
|
SQL 数据挖掘 数据库

热门文章

最新文章