Java 中 super 和 this关键字总结
super 和 this 都能用来引用对象,但使用场景和指向的对象有所不同。
1. 基本概念
-
this:表示当前对象本身,即调用该方法或访问该变量的对象实例。
-
super:表示当前对象的父类部分,常用于访问父类的属性、方法或构造方法。
2. 使用场景
(1)访问成员变量
-
this:用于区分成员变量和方法参数的同名情况。
-
super:当子类覆盖了父类同名成员时,可以用 super 访问父类的变量。
class Animal {String name = "Animal";
}class Dog extends Animal {String name = "Dog";void showName() {System.out.println(this.name); // DogSystem.out.println(super.name); // Animal}
}
(2)调用成员方法
this:调用当前类的方法(必要时也可以省略)。
super:调用父类中被子类覆盖(重写)的方法。
class Animal {void eat() {System.out.println("Animal eats");}
}class Dog extends Animal {@Overridevoid eat() {System.out.println("Dog eats");}void showEat() {this.eat(); // 调用子类方法 → Dog eatssuper.eat(); // 调用父类方法 → Animal eats}
}
(3)构造方法调用
使用 this()
-
在构造方法中调用本类的其他构造方法;
-
必须放在构造方法的第一行。
使用 super()
-
在子类构造方法中调用父类的构造方法;
-
同样必须放在构造方法的第一行;
-
若未显式写出,编译器会自动插入 super(); 调用父类无参构造。
class Animal {// 父类无参构造Animal() {System.out.println("Animal 的无参构造方法被调用");}// 父类有参构造Animal(String type) {System.out.println("Animal 的有参构造方法被调用,type = " + type);}
}class Dog extends Animal {// 子类无参构造Dog() {super(); // 调用父类的无参构造方法System.out.println("Dog 的无参构造方法被调用");}// 子类有参构造Dog(String name) {this(); // 调用本类的无参构造方法System.out.println("Dog 的有参构造方法被调用,name = " + name);}
}public class Test {public static void main(String[] args) {Dog d1 = new Dog();System.out.println("---");Dog d2 = new Dog("旺财");}
}
输出:
Animal 的无参构造方法被调用
Dog 的无参构造方法被调用
---
Animal 的无参构造方法被调用
Dog 的无参构造方法被调用
Dog 的有参构造方法被调用,name = 旺财
(4) this 作为参数传递
有时候我们希望把当前对象传给另一个方法,就可以用 this。
class Printer {void printDog(Dog dog) {System.out.println("打印了一只狗对象:" + dog);}
}class Dog {void show(Printer printer) {// 传递当前对象给 Printer 的方法printer.printDog(this);}
}public class Test {public static void main(String[] args) {Dog d = new Dog();Printer p = new Printer();d.show(p);}
}
输出:
打印了一只狗对象:Dog@1b6d3586
(5)this 作为返回值
this 还可以作为返回值,用于链式调用。比如“建造者模式”或者“连续设置属性”的场景。
class Person {Person setName(String name) {System.out.println("设置名字:" + name);return this; // 返回当前对象}Person setAge(int age) {System.out.println("设置年龄:" + age);return this; // 返回当前对象}
}public class Test {public static void main(String[] args) {// 链式调用:连续调用同一个对象的方法Person p = new Person();p.setName("小明").setAge(20);}
}
输出:
设置名字:小明
设置年龄:20