一、this
概念:this代表着当前对象的引用,this代表的是执行者,this本质是一个执行当前对象的指针
- 最常见的情况是是对象的属性因为与构造器参数同名而被构造器参数屏蔽时,如果需要调用对象被屏蔽的属性,需要用用this进行标识,例如this.name指的是我这里的调用的是当前对象的属性name而不是构造器的局部变量参数name
1 //局部变量name和age屏蔽了name和age属性,用this进行标识 2 public Person(String name, int age,String nation) { 3 this.name = name; 4 this.age = age; 5 }
- this只能在方法内使用,表示正在调用方法的那个对象,但是如果在方法内调用同一个类的另一个方法,就不必使用this,直接调用即可,this关键字是能省则省
1 public class Person{ 2 public void test(){ 3 System.out.println("测试"); 4 } 5 6 public void test2(){ 7 //以下这两行是等价,推荐第二种写法 8 this.test(); 9 test() 10 } 11 }
-
this和static的关系:
static方法是类方法,依附于类而不依赖与任何对象,static属性是指该属性是类中所有对象所共享的,static方法是类方法,先于任何实例(对象)存在,static在类加载时就已经存在了,但对象是在创建时才生成;方法中使用this关键字它的值是当前对象的引用,只能用它调用属于当前对象的属性和方法和。但是,this可以调用static类型的属性,举个例子:一个父亲是不可能向他还未出生的孩子借钱的,但孩子出生后完全可以找他父亲去借钱,总之:static方法或static代码块内不能出现this,但是this可以调用到静态属性和静态方法1 public class Person { 2 public static String nation = "Chinese"; 3 4 public static String getNation(){ 5 return nation; 6 } 7 8 @Test 9 public void test(){ 10 System.out.println(this.nation); //Chinese 11 System.out.println(this.getNation());//Chinese 12 } 13 }
- 对于一个类中的this,不一定单指这个的对象,也可能是这个类的子类的对象(抽象类里面的this只能是实际调用中它的派生类的实例化对象,因为抽象类本身不能实例化);总之:如果new 父类对象的话,父类方法的this指向的是父类,如果new 子类,那么父类方法的this指向的是子类
1 class Student extends Person{ 2 private String name; 3 private int age; 4 5 public Student(String name, int age) { 6 super(name, age); 7 } 8 } 9 10 public class Person{ 11 private String name; 12 private int age; 13 14 public Person(String name, int age) { 15 this.name = name; 16 this.age = age; 17 } 18 19 @Override 20 public String toString() { 21 return "Person/Student{" + 22 "name='" + name + '\'' + 23 ", age=" + age + 24 '}'; 25 } 26 27 public void print(){ 28 System.out.println(this.toString()); 29 } 30 31 public static void main(String[] args) { 32 Student student = new Student("student", 11); 33 Person person = new Person("person",12); 34 //此时print中的this代表的是Student的实例对象 35 student.print();//Person/Student{name='student', age=11} 36 //此时print中的this代表的是Person的实例对象 37 person.print();//Person/Student{name='person', age=12} 38 } 39 }
- this关键字也可以用于在构造函数中调用其他构造函数。但是,只能定义在构造函数的第一行,因为初始化动作要先执行,如果是用this调用本列无参构造器可省略,如果用this调用的是有参构造器就不能省略,而且this只能调用一次构造器
1 public class Person{ 2 private String name; 3 private int age; 4 5 public Person() { } 6 7 public Person(String name) { 8 this(); //作用是调用本类的无参构造,可以省略 9 this.name = name; 10 } 11 12 public Person(int age) { 13 this();//作用是调用本类的无参构造,可以省略 14 this.age = age; 15 } 16 17 public Person(String name, int age) { 18 this(name); 19 this.age = age; 20 } 21 }
二、super
概念:super可以理解为“父类的”,super可以在子类中调用父类的属性,方法,构造器,super关键字和this一样能省就省,super在java的子类中指代父类引用,是一个关键字注意点:
1、this和super很像,this指向的是当前对象的调用,super指向的是当前调用对象的父类
2、类加载完毕,创建对象,父类的构造方法会被调用父类如果重写了无参构造器或者父类中没有有参构造器,那么子类的构造方法第一行就是super(),可以省略
1 class Student extends Person{ 2 //这是默认的构造器内容,写出来是为了帮大家理解 3 public Student(){ 4 super(); 5 } 6 } 7 8 public class Person{ 9 private String name; 10 private int age; 11 }
3.子类相应构造创建了一个子类对象,该子类对象还包含了一个父类对象。该父类对象在子类对象内部(正如子类的构造器无论如何都要通过super调用父类构造器一样,子类的对象被成功构造,那么它的内部就会包含父类的对象),证明如下
- 子类重写父类的方法后可以通过super调用到父类的方法
1 class Student extends Person{ 2 3 public Student(String name, int age) { 4 //任选一个父类有参构造 5 //super(name, age); 6 super(name); 7 } 8 } 9 10 public class Person{ 11 private String name; 12 private int age; 13 14 public Person(String name, int age) { 15 this.name = name; 16 this.age = age; 17 } 18 19 public Person(String name) { 20 this.name = name; 21 } 22 }
子类获取到父类的变量
1 class Student extends Person{ 2 3 public void parentDisplay(){ 4 System.out.println(super.age + super.name); 5 } 6 7 public static void main(String[] args) { 8 new Student().parentDisplay(); //输出结果:20wzh 9 } 10 } 11 12 public class Person{ 13 //protected意味着子类和同一包中可以访问 14 protected String name = "wzh"; 15 protected int age = 20; 16 }
4、this super只能在有对象的前提下使用,不能在静态上下文使用 5、如果一个类没有基础任何父类,super还有用吗?肯定有用,可以调用Object中的方法
1 public class Person{ 2 private String name; 3 private int age; 4 5 public void display(){ 6 //通过this或super调用到了Object的toString(); 7 System.out.println(super.toString()); 8 } 9 10 public static void main(String[] args) { 11 new Person().display(); //输出为Person@452b3a41 12 } 13 14 }
- 子类重写父类的方法后可以通过super调用到父类的方法