活动地址:CSDN21天学习挑战赛
✨博客主页: XIN-XIANG荣
✨系列专栏:【Java SE】
✨一句短话: 难在坚持,贵在坚持,成在坚持!
文章目录
一. this引用
1. this引用的介绍
- this引用是成员方法的参数之一,不需要用户传递实现,由编译器自动完成,也就是说,这个参数用户是看不到的,但用户可使用这个参数。
- this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。 只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
- this 引用的是调用成员方法的对象。
2. this引用的特性
- this的类型:对应类 类型引用,即哪个对象调用就是哪个对象的引用类型
- this只能在"成员方法"中使用
- 在"成员方法"中,this只能引用当前对象,不能再引用其他对象
- this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法对象的引用传递给该成员方法,this负责来接收
- 用户也可以将由编译器实现的形参this手动给出,但实参中不能有其对应的对象的引用,否则会报错
3. this引用所解决的问题
看下面给出的代码,当方法形参名与成员变量名相同;但我们没有手动通过this引用去调用成员变量;
看执行结果可以发现此时并没有完成对于成员变量的赋值,因为在方法中遵循局部变量优先的原则,就不会去访问成员变量,只是形参自己给自己赋值而已
publicclassDate{publicint year;publicint month;publicint day;publicvoidsetDay(int year,int month,int day){
year = year;
month = month;
day = day;}publicvoidprintDate(){System.out.println(year +"/"+ month +"/"+ day);}publicstaticvoidmain(String[] args){// 构造三个日期类型的对象 d1 d2 d3Date d1 =newDate();Date d2 =newDate();Date d3 =newDate();// 对d1,d2,d3的日期设置
d1.setDay(2022,8,15);
d2.setDay(2022,8,16);
d3.setDay(2022,8,17);// 打印日期中的内容
d1.printDate();
d2.printDate();
d3.printDate();}}
执行结果:
要解决这里的问题只需要通过this去访问成员变量即可,此时就可以区分形参和成员变量了
publicvoidsetDay(int year,int month,int day){this.year = year;this.month = month;this.day = day;}
执行结果:
4. this的三种用法
- this.成员变量
- this.成员方法
- this( );访问构造方法(在构造方法博客中介绍)
二. super关键字
1. super关键字的介绍
由于设计不好,或者因场景需要,子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成 员时,该如何操作?
直接访问是无法做到的,因为局部优先的的原则,会直接访问子类的成员。
Java提供了super关键字,该关键字主要作用:在子类方法中访问父类的成员。
【注意事项】
- super只能在非静态方法中使用
- super可以用来在子类方法中,访问父类的成员变量和方法。
publicclassBase{int a;int b;publicvoidmethodA(){System.out.println("Base中的methodA()");}publicvoidmethodB(){System.out.println("Base中的methodB()");}}classDerivedextendsBase{int a;// 与父类中成员变量同名且类型相同char b;// 与父类中成员变量同名但类型不同// 与父类中methodA()构成重载publicvoidmethodA(int a){System.out.println("Derived中的method()方法");}// 与基类中methodB()构成重写publicvoidmethodB(){System.out.println("Derived中的methodB()方法");}publicvoidmethodC(){// 对于同名的成员变量,直接访问时,访问的都是子类的
a =100;// 等价于: this.a = 100;
b =101;// 等价于: this.b = 101;// 注意:this是当前对象的引用// 访问父类的成员变量时,需要借助super关键字// super是获取到子类对象中从基类继承下来的部分super.a =200;super.b =201;// 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法methodA();// 没有传参,访问父类中的methodA()methodA(20);// 传递int参数,访问子类中的methodA(int)// 如果在子类中要访问重写的基类方法,则需要借助super关键字methodB();// 直接访问,则永远访问到的都是子类中的methodA(),基类的无法访问到super.methodB();//访问基类的methodB()}}
2. super的三种用法
- super.子类中从父类继承的成员变量
- super.子类中从父类继承的成员方法
- super( );调用父类的构造方法(在构造方法博客中介绍)
三. super和this的比较
1. 相同点
- 都是Java中的关键字
- 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
- 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
2. 不同点
- this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是子类对象中从父类继承下来部分成员的引用(注意不是父类的引用,子类继承父类并没有创建父类对象)
- 在非静态成员方法中,this用来访问本类的方法和属性,子类对象中如果没有重名现象的发生,this也可以访问到父类继承下来的方法和属性;但super只能用来用来访问父类继承下来的方法和属性
- 在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现
- 子类构造方法中一定会存在super(…)的调用,用户没有写编译器也会自动给出;但是要在子类构造方法中调用子类其他构造方法,需要用户手动添加this(…)
四. 代码块概念以及分类
使用 { } 定义的一段代码称为代码块。
根据代码块定义的位置以及关键字,又可分为以下四种:
- 普通代码块
- 构造代码块
- 静态代码块
- 同步代码块
1. 普通代码块
普通代码块:定义在方法中的代码块, 其内的变量只在代码块中有效,这种用法较少见。
publicclassMain{publicstaticvoidmain(String[] args){{//直接使用{ }定义,普通方法块int x =10;System.out.println("x1 = "+x);}int x =100;System.out.println("x2 = "+x);}}
2. 构造代码块
定义在类中的代码块(不加修饰符)。
也叫:实例代码块。构造代码块一般用于初始化实例成员变量。
publicclassStudent{//实例成员变量privateString name;privateString gender;privateint age;//实例代码块{this.name ="xinxin";this.age =21;this.gander ="nan";System.out.println("I am instance init()!");}publicvoidshow(){System.out.println("name: "+name+" age: "+age+" gender: "+gender);}}publicclassMain{publicstaticvoidmain(String[] args){Student stu =newStudent();
stu.show();}}
3. 静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
publicclassStudent{privateString name;privateint age;privatestaticString classRoom;//实例代码块{this.name ="xin";this.age =21;System.out.println("I am instance init()!");}// 静态代码块static{
classRoom ="rj2104";System.out.println("I am static init()!");}publicstaticvoidmain(String[] args){Student s1 =newStudent();Student s2 =newStudent();}}
4. 注意事项
- 静态代码块不管生成多少个对象,其只会执行一次
- 静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
- 如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
- 实例代码块只有在创建对象时才会执行
版权归原作者 XIN-XIANG荣 所有, 如有侵权,请联系我们删除。