关于java关键字this和super的区别和理解
作者:智欧巴 发布时间:2022-08-01 14:33:09
this:
this理解为:当前对象 或 当前正在创建的对象
可以调用的结构:属性、方法;构造器
this调用属性、方法:
先了解一下形参:
形参的意义就是给属性赋值,我们是要给同名的属性赋值,这时候我们就把形参名和属性的名字写成一样,这样我们就知道我们传入的形参就是要给我们同名的属性去赋值的.
在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是,
通常情况下,我们都择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
举例:我们声明一个类叫鞋类,给它提供私有的属性和get/set方法和构造器:
//声明一个鞋类
public class shoes {
//鞋的属性
private String name;//鞋名
private int id;//编号
//无参构造器
public shoes() {
}
//有参构造器:
public shoes(String name, int id) {
// name = name;没加this
this.name = name;
// id = id; 没加this
this.id = id;
}
//声明两个方法
public void show(){
System.out.println("展示~~");
sale();//show方法中调sale方法
// this.sale();//this可省略
}
public void sale(){
System.out.println("售卖~~");
}
//get/set方法:
public String getName() {
return name;
}
public void setName(String name) {
//name = name;没加this
this.name = name;
}
public void setId(int id) {
//id = id;没加this
this.id = id;
}
public int getId() {
return id;
}
}
//测试
class test {
public static void main(String[] args) {
//我们先实例化鞋类的对象来调它的属性
shoes s = new shoes();
s.setName("nike");//这里的"nike"就是传入的形参
System.out.println(s.getName());
//我们获取鞋名的时候,获取不到,意思就是形参的值又赋给了形参,代表没有给鞋的属性赋上值
//这个时候控制台会输出传入的形参数据类型的默认值,明显不是我们想看到的结果
s.setId(1);
System.out.println(s.getId());//鞋的id类似的也会出现同样的情况
//"this.方法"举例:
s.show();
/*我们先调的是show自己的方法体,然后在show方法中调了sale方法
意思是s这个对象调了show方法,我们就用调show方法的这个对象s来调sale方法,
其实在sale();前面也省略了this关键字,表示当前对象(就是调show方法的对象)调的sale方法*/
System.out.println("------------------------分割线--------------------");
shoes s1 = new shoes("李宁",2);//我们new的有参数的对象给它赋初值之后
System.out.println(s1.getName());
System.out.println(s1.getId());//如果没有加this,结果还是和没有获取到鞋名和编号
}
}
先来看没有加this关键字的情况:
结果:
然后我们给鞋属性加上this关键字:
控制台输出的就是我们给鞋设置的名字和编号:
在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用当前正在创建的对象属性或方法。但是,通常情况下,我们都择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
同样的我们的构造器也是一样:如果有参构造器没有加给属性加this关键字:控制台输出结果也和上面一样
加上之后:
"this.方法"举例:我们声明两个方法show和sale方法来举例体会一下this的作用:代码参照上面:
s.show();的结果:
this调用构造器:
① 我们在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器
② 构造器中不能通过"this(形参列表)“方式调用自己
③ 如果一个类中有n个构造器,则最多有 n - 1构造器中使用了"this(形参列表)”
④ 规定:"this(形参列表)“必须声明在当前构造器的首行
⑤ 构造器内部,最多只能声明一个"this(形参列表)”,用来调用其他的构造器
举例:我们还是写一个Shoes类 提供私有属性和get/set方法并提供三个构造器:
public class Shoes {
//属性
private String name;//鞋名
private int id;//编号
//get/set方法:
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
//构造器1
public Shoes() {
System.out.println("构造器1");
}
//构造器2
public Shoes(int id){
this();//调构造器1
System.out.println("构造器2");
this.id = id;
}
//构造器3
public Shoes(String name, int id) {
//通过调用构造器来执行其他构造器中的代码
this(id);//调构造器2
// this.id = id;//交给构造器2来执行
this.name = name;
//我们如果需要使用到其他构造器中的代码就可以使用"this.构造器"的方式
//这里只是为了举例我们只写了一行输出语句,真正实际中我们写的代码多了,调用构造器的方法的优势就体现出来了
//这样我们可以减少代码的冗余,提高程序执行效率
}
}
class test{
public static void main(String[] args) {
//用构造器3来实例化对象,我们在构造器3中没有把参数id赋给当前对象
//但是通过调构造器2,构造器2中执行了 this.id = id;把id赋给了当前对象的属性
//所以我们才可以得到当前对象s3的id
Shoes s3 = new Shoes("adidas",2021);
System.out.println(s3.getId());
}
}
运行结果:
super:
super 关键字可以理解为:父类的
可以用来调用的结构:
属性、方法、构造器
super调用属性、方法:
我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."
①特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。
② 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法(也就是父类中原本的方法)。
举例两种特殊情况:在子类的方法中调用父类中同名的属性和方法:
创建一个人类,一个学生类,学生类继承人类,和一个测试类
//人类
public class Person {
//属性
String name = "普通人";//姓名
int id = 1234;//身份证号
//方法
public void learn(){
System.out.println("人要学习");
}
}
//学生类
public class Student extends Person {
//声明了与父类的同名属性
String name = "哈利波特";//姓名
int id = 9527;//学号
@Override//子类重写父类的方法
public void learn() {
System.out.println("学生要努力学习");
super.learn();//调父类中原本的方法
System.out.println("姓名:"+name);//子类自己的属性
System.out.println("学号:"+id);
System.out.println("姓名:"+super.name);//父类中声明的属性
System.out.println("身份证号:"+super.id);
}
}
//测试类
public class Test {
public static void main(String[] args) {
//实例化子类对象
Student student = new Student();
//调子类中重写父类的方法
student.learn();
}
}
输出结果:
super调用构造器:
我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
注意:
"super(形参列表)"的使用,必须声明在子类构造器的首行!我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二者取其一,不能同时出现在构造器的首行,没显式的声明"this(形参列表)“或"super(形参列表)”,则默认调用的是父类中空参的构造器:super()在类的多个构造器中,至少一个类的构造器中使用了"super(形参列表)",调用父类中的构造器
举例:还是用上面的例子,我们在人类和学生类中添加构造器:
public class Person {
//属性
String name = "普通人";//姓名
int id = 1234;//身份证号
//构造器
public Person() {
}
public Person(String name, int id) {
this.name = name;
this.id = id;
}
//方法
public void learn(){
System.out.println("人要学习");
}
}
public class Student extends Person {
//声明了与父类的同名属性
String name = "哈利波特";//姓名
int id = 9527;//学号
//构造器1
public Student(String name, int id) {
this.name = name;
this.id = id;
}
//构造器2
public Student(String name, int id, String name1, int id1) {
super(name, id);//调用父类已有的构造器
this.name = name1;
this.id = id1;
}
@Override//子类重写父类的方法
public void learn() {
System.out.println("学生要努力学习");
super.learn();//调父类中原本的方法
System.out.println("姓名:"+name);//子类自己的属性
System.out.println("学号:"+id);
System.out.println("姓名:"+super.name);//父类中声明的属性
System.out.println("身份证号:"+super.id);
}
}
在子类构造器2中调用父类已有的有参构造器:
然后测试:实例化学生类的对象并给属性赋值,调learn方法:
public class Test {
public static void main(String[] args) {
Student student = new Student("人",8888,"学生",2021);
student.learn();
}
}
输出结果:
this与super的区别总结:
①代表事物不同
this表示当前所属函数的调用者对象
super表示调用父类的结构(属性,方法,构造器)
②使用前提不同
super必须要有继承关系才能使用
this不需要继承关系也能使用
③调用的构造器不同
super:调用父类的构造器
this:调用当前类(本类)的构造器
说明:
在栈空间中存放的是对象的引用也就是对象名指向堆空间中new的对象,在堆空间中子类和父类的属性都会有,this和super都可以通过栈空间的引用指向堆空间来调用具体的属性.
继续加油~~冲冲冲! ! !
总结
来源:https://blog.csdn.net/weixin_44015158/article/details/113406809


猜你喜欢
- 前言本次主要是实现一个Android应用,实现静态广播、动态广播两种改变 widget内容的方法,即在上篇博文中实验的基础上进行修改,所以此
- 这次是列表滑动删除的第三波,仿微信的列表滑动删除。先上个效果图: 前面的文章里面说过开源框架SwipeListView
- 前言EventBus框架EventBus是一个通用的叫法,例如Google出品的Guava,Guava是一个庞大的库,EventBus只是它
- 单例模式为什么要用单例确保某个类只有一个对象,常用于访问数据库操作,服务的配置文件等。单例的关键点1、默认构造函数为private,复制构造
- 本文实例为大家分享了C#实现文件上传与下载的具体代码,供大家参考,具体内容如下C#实现文件上传代码: public ActionResult
- mybatis-plus实现in嵌套sql今天使用jeegboot看源码时发现用户权限部分的代码条件查询的inSql方法的用法:即sql中的
- 苹果的iphone 有语音识别用的是Google 的技术,做为Google 力推的Android 自然会将其核心技术往Android 系统里
- 本文实例总结了Android实现屏幕旋转方法。分享给大家供大家参考。具体如下:在介绍之前,我们需要先了解默认情况下android屏幕旋转的机
- 太多的if-else不太直观,难以维护。 以下面代码为例,展示几种替代if else的方法。String input = &quo
- 由于大多数便携式设备支持浏览图片而不支持浏览PowerPoint 文件,所以相比较而言,图像对于用户而言更加友好。除此之外,将PowerPo
- 前言:微信公众号提供了用户和用户组的管理,我们可以在微信公众号官方里面进行操作,添加备注和标签,以及移动用户组别,同时,微信公众号提供了相应
- 一:什么是Hystrix在分布式环境中,许多服务依赖项中的一些将不可避免地失败。Hystrix是一个库,通过添加延迟容差和容错逻辑来帮助您控
- 从Handler.post()说起Handler.post()是用来发送消息的,我们看下Handler源码的处理:public final
- 在上篇文章给大家介绍了使用XSD校验Mybatis的SqlMapper配置文件的方法(1),需要的朋友可以参考下。编写好XSD文件,然后来看
- 每一个应用都是具备一个功能,那就是版本更新,我记得我之前在面试的时候,面试官让我介绍一下应用版本更新的一些具体操作。我当时因为做过这个功能,
- 目录前言解决方案前言我们在开发Spring应用时可能会不小心注入两个相同类型的Bean,比如实现了两个相同Service接口的类,示例伪代码
- 简介lombok是一个编译级别的插件,它可以在项目编译的时候生成一些代码。比如日常开发过程中需要生产大量的JavaBean文件,每个Java
- 本文实例为大家分享了Android仿微信录制语音的具体代码,供大家参考,具体内容如下前言我把录音分成了两部分1.UI界面,弹窗读秒 2.一个
- SpringBoot的主要目的是简化配置文件,通过少量配置即可运行Java程序,其强大的自动配置功能帮助开发者轻松实现配置装配,通过引入Sp
- 在日常开发中,可能会遇到同一份代码,需要根据运营需求打出不同包名、不同图标、不同名称的Apk,发布到不同的渠道中。Android Studi