查看“Super和this”的源代码
←
Super和this
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看和复制此页面的源代码。
https://www.bilibili.com/video/BV1bq4y1a73a/ super 代表父类,this 代表当前对象。 === this === ==== this.成员属性 ==== 先来看 this,<syntaxhighlight lang="java"> public class Person { private String name; private Integer age; public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } } </syntaxhighlight>当我们用 IDE 自动生成 set 方法时,通常会用 this.成员属性来接收参数,因为参数名和成员属性名相同, 我们必须得指定成员属性才不会冲突,所以这里 this 的作用就是指定当前对象的成员属性。 ==== this.成员方法 ==== 既然都能指定当前对象的成员属性,那成员方法当然也可以通过 this 调用,<syntaxhighlight lang="java"> public class Person { public void f1() { //这两行代码完全等价 f2(); this.f2(); } public void f2() { System.out.println("f2"); } } </syntaxhighlight>不过成员方法不会像参数名那样命名冲突,所以我们一般省略 this 关键字,直接调用成员方法。 当然,在参数名没有冲突的情况下,<syntaxhighlight lang="java"> public class Person { private String name; private Integer age; public void setName(String aName) { //省去this关键字 name = aName; } public void setAge(Integer age) { this.age = age; } } </syntaxhighlight>省略 this 关键字来直接调用成员属性也是没问题的。 ==== this 调用构造方法 ==== 成员属性和成员方法讲完了,还差一个构造方法。<syntaxhighlight lang="java"> public class Person { private String name; private Integer age; public Person() { this("匿名", 18); } public Person(Integer age) { this("匿名", age); } public Person (String name) { this(name, 18); } public Person(String name, Integer age) { this.name = name; this.age = age; } } </syntaxhighlight>直接使用 this 加上括号就代表调用本类的构造方法,这种方式用在构造方法中可以复用其它构造方法的逻辑, 比如上段代码中最底部的构造器已经完成了属性的赋值逻辑,其它构造方法就没必要再写重复的赋值逻辑了,直接传值就好,this 关键字讲完。 === super === 再来看下 super 关键字,super 和 this 一样,都可以调用成员属性、成员方法和构造方法。 只不过 super 调用的是父类的东西。 重写一个父类方法时,可以完全覆盖父类的所有逻辑,<syntaxhighlight lang="java"> class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } public void introduce() { System.out.printf("我名叫%s,今年%d岁。", name, age); } } public class Student extends Person { public Student(String name, Integer age) { super(name, age); } @Override public void introduce(){ // 复用父类逻辑 super.introduce(); System.out.println("我是一名学生。"); } } </syntaxhighlight>但若只是想在父类的基础上扩展一些自定义的逻辑呢? 这时就可以用到 super 关键字来调用父类方法,从而复用父类的逻辑,调用父类的成员属性就是 super.成员属性(只能调用非private的成员属性)。 通过 super 关键字调用父类构造方法的场景。 对象实例化执行动作的先后顺序 {| class="wikitable" !父类:静态属性/静态代码块 |- !↓ |- !子类:静态属性/静态代码块 |- !↓ |- !父类:成员属性/普通代码块 |- !↓ |- !父类:构造器 |- !↓ |- !子类:成员属性/普通代码块 |- !↓ |- !子类:构造器 |} 除了可选择性地复用逻辑外,在某些时候必须手动调用 super 构造方法,因为子类在构造时必须先得完成父类构造,<syntaxhighlight lang="java"> class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } } public class Student extends Person { public Student() { //编译失败,因为父类没有无参构造方法 } } </syntaxhighlight><syntaxhighlight lang="java"> class Person { private String name; private Integer age; public Person(String name, Integer age) { this.name = name; this.age = age; } } public class Student extends Person { public Student(String name, Integer age) { //编译成功,因为指定了父类的构造方法 super(name, age); } } </syntaxhighlight>也就是说在所有构造方法中,第一行逻辑必须是调用父类的构造方法。 平常写代码时没有通过 super 调用构造器是因为<big>'''编译器会默认在第一行加上父类的无参构造方法'''</big>, '''<big>如果父类只有有参构造器,没有无参构造器,那就必须通过 super 关键字来手动调用父类的构造,否则就会编译失败</big>'''。 还要注意,在被 static 修饰的地方(成员属性、成员方法里、方法块里)是调用不了 super 和 this 的,因为这两者都和对象相关。
返回至
Super和this
。
导航菜单
个人工具
登录
名字空间
页面
讨论
变种
视图
阅读
查看源代码
查看历史
更多
搜索
导航
首页
Spring Boot 2 零基础入门
Spring Cloud
Spring Boot
设计模式之禅
VUE
Vuex
Maven
算法
技能树
Wireshark
IntelliJ IDEA
ElasticSearch
VirtualBox
软考
正则表达式
程序员精讲
软件设计师精讲
初级程序员 历年真题
C
SQL
Java
FFmpeg
Redis
Kafka
MySQL
Spring
Docker
JMeter
Apache
Linux
Windows
Git
ZooKeeper
设计模式
Python
MyBatis
软件
数学
PHP
IntelliJ IDEA
CS基础知识
网络
项目
未分类
MediaWiki
镜像
问题
健身
国债
英语
烹饪
常见术语
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息