共计 3795 个字符,预计需要花费 10 分钟才能阅读完成。
文章目录
一. this 援用
1. this 援用的介绍
- this 援用是成员办法的参数之一,不须要用户传递实现,由编译器主动实现,也就是说,这个参数用户是看不到的,但用户可应用这个参数。
- this 援用指向以后对象(成员办法运行时调用该成员办法的对象),在成员办法中所有成员变量的操作,都是通过该援用去拜访。只不过所有的操作对用户是通明的,即用户不须要来传递,编译器主动实现。
- this 援用的是调用成员办法的对象。
2. this 援用的个性
- this 的类型:对应类 类型援用,即哪个对象调用就是哪个对象的援用类型
- this 只能在 ” 成员办法 ” 中应用
- 在 ” 成员办法 ” 中,this 只能援用以后对象,不能再援用其余对象
- this 是“成员办法”第一个暗藏的参数,编译器会主动传递,在成员办法执行时,编译器会负责将调用成员办法对象的援用传递给该成员办法,this 负责来接管
- 用户也能够将由编译器实现的形参 this 手动给出,但实参中不能有其对应的对象的援用,否则会报错
3. this 援用所解决的问题
看上面给出的代码,当办法形参名与成员变量名雷同;但咱们没有手动通过 this 援用去调用成员变量;
看执行后果能够发现此时并没有实现对于成员变量的赋值,因为在办法中遵循局部变量优先的准则,就不会去拜访成员变量,只是形参本人给本人赋值而已
public class Date {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
year = year;
month = month;
day = day;
}
public void printDate(){System.out.println(year + "/" + month + "/" + day);
}
public static void main(String[] args) {
// 结构三个日期类型的对象 d1 d2 d3
Date d1 = new Date();
Date d2 = new Date();
Date d3 = new Date();
// 对 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 去拜访成员变量即可,此时就能够辨别形参和成员变量了
public void setDay(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 能够用来在子类办法中,拜访父类的成员变量和办法。
public class Base { int a; int b; public void methodA(){System.out.println("Base 中的 methodA()"); } public void methodB(){System.out.println("Base 中的 methodB()"); } } class Derived extends Base{ int a; // 与父类中成员变量同名且类型雷同 char b; // 与父类中成员变量同名但类型不同 // 与父类中 methodA()形成重载 public void methodA(int a) {System.out.println("Derived 中的 method()办法"); } // 与基类中 methodB()形成重写 public void methodB(){System.out.println("Derived 中的 methodB()办法"); } public void methodC(){ // 对于同名的成员变量,间接拜访时,拜访的都是子类的 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. 一般代码块
一般代码块:定义在办法中的代码块,其内的变量只在代码块中无效,这种用法较少见。
public class Main{public static void main(String[] args) {
{// 间接应用 {} 定义,一般办法块
int x = 10 ;
System.out.println("x1 =" +x);
}
int x = 100 ;
System.out.println("x2 =" +x);
}
}
2. 结构代码块
定义在类中的代码块(不加修饰符)。
也叫:实例代码块。结构代码块个别用于初始化实例成员变量。
public class Student{
// 实例成员变量
private String name;
private String gender;
private int age;
// 实例代码块
{
this.name = "xinxin";
this.age = 21;
this.gander = "nan";
System.out.println("I am instance init()!");
}
public void show(){System.out.println("name:"+name+"age:"+age+"gender:"+gender);
}
}
public class Main {public static void main(String[] args) {Student stu = new Student();
stu.show();}
}
3. 动态代码块
应用 static 定义的代码块称为动态代码块。个别用于初始化动态成员变量。
public class Student{
private String name;
private int age;
private static String classRoom;
// 实例代码块
{
this.name = "xin";
this.age = 21;
System.out.println("I am instance init()!");
}
// 动态代码块
static {
classRoom = "rj2104";
System.out.println("I am static init()!");
}
public static void main(String[] args) {Student s1 = new Student();
Student s2 = new Student();}
}
4. 注意事项
- 动态代码块不论生成多少个对象,其只会执行一次
- 动态成员变量是类的属性,因而是在 JVM 加载类时开拓空间并初始化的
- 如果一个类中蕴含多个动态代码块,在编译代码时,编译器会依照定义的先后秩序顺次执行(合并)
- 实例代码块只有在创建对象时才会执行
正文完