导航
我们为什么需要this与super关键字?
由于Java有方法的重载与重写、继承关系、作用域等的存在,常常会有重名的现象发生。当名字一样时,我们如何区分出我们想要的那一个呢?这时,this与super就派上了用场。
当然,this与super不仅仅只是用来解决重名问题。他俩的具体用法如下:
this关键字
this关键字:指向自己的引用。通俗的说,就是指当前正在使用的对象(的地址)。
举例子讲用法,理解的最快,我在这列举一些this的用法种类:
1.区分成员变量与局部变量
我们这里先谈谈变量的分类:
-
类变量:独立于方法之外的变量,用 static 修饰。
-
成员变量(实例变量):在类中定义的变量,为成员变量,也被称为实例变量。(这里我又想吐槽了,对同一个东西的称呼名词太多,不统一。。。)
-
局部变量:类的方法中的变量,称为局部变量。
当我们在类方法中如果局部变量和成员变量重名时,不加this,则都是指的局部变量。此时为了区分成员变量与局部变量,我们通过this标出成员变量。
class Person{
private String name;
private int age;
Person(String name,int age) {
this.name = name ; // this.name 表示 person类的name变量;name表示传入的参数,局部变量
this.age = age;
}
}
2.在同类中,实例方法的调用。(可以省略)
我们称方法前有satic关键字修饰的为类方法,无关键字的为实例方法。类方法的调用应该是通过类名( 为什么是通过类名调用,可以查看我的《static修饰符》),在同类中实例方法的调用则是通过this,但这种情况下this关键字可以省略。
class Animal{
void breath() {
System.out.println("呼吸");
}
void eatFood() {
this.breath(); // 调用同类中的其他实例方法
breath(); // 省略this也可以
System.out.println("吃吃吃");
}
}
3.作为参数传递
调用函数,可以将正在使用的对象,当作参数传入。实例:
class Cat{
static void catchMouse(Mouse m) { // 需要传入一个Mouse对象
System.out.println("抓住了:"+m.name);
}
}
class Mouse{
String name;
void beCaught() {
Cat.catchMouse(this); // this指,调用这个方法的Mouse实例对象
}
}
public class Test {
public static void main(String[] args){
Mouse mouse1 = new Mouse();
mouse1.name = "Jerry";
mouse1.beCaught();
}
}
-----------------------------------
输出结果:
抓住了:Jerry
4.作为返回值返回
和作为参数传递类似,将正在使用的对象返回。
class Cat{
String name;
Cat catchMouse() {
System.out.println(this.name+"抓住了老鼠");
return this;
}
}
public class Test {
public static void main(String[] args){
Cat cat1 = new Cat();
cat1.name = "Tom";
Cat cat2 = cat1.catchMouse(); //返回的this,是一个Cat对象,先装起来
System.out.println(cat1);
System.out.println(cat2);
System.out.println(cat1 == cat2); // 比较一下两个地址。相同,证明this就是指当前正在使用的对象
}
}
------------------------------------------
输出结果:
Tom抓住了老鼠
com.project.test.Cat@7852e922
com.project.test.Cat@7852e922
true
5.使用static修饰的方法里不能使用this
因为static在jvm启动时就会放在方法区里,但此时并不知道this指的是哪一个。
6.用于在构造器中调用另一个构造器
由于重载的存在,所有可以有多个构造器。当在一个构造器里,我们想要调用另一个重载的构造器时,可以用this去调用,且需要放在该构造器第一行。实例:
class Person{
private String name;
private int age;
Person(String name){
this.name = name;
}
Person(int age){
this.age = age;
}
Person(String name,int age){
this(name); // 这里的this,指调用Person(String name)构造方法
// this(age); // 会报错。由于用this调用构造器,必须放在第一行,所有不能使用this调用两次构造器
this.age = age;
}
}
super关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
1.调用父类方法
当我们在子类中重写的父类的方法,但又想调用父类的方法。实例:
class Animal{
void eatFood() {
System.out.println("吃吃吃");
}
}
class Cat extends Animal{
@Override
void eatFood() {
super.eatFood(); // 调用父类的eatFood方法
System.out.println("吃小鱼干");
}
}
public class Test {
public static void main(String[] args){
Cat cat1 = new Cat();
cat1.eatFood();
}
}
-----------------------------------------
输出结果:
吃吃吃
吃小鱼干
2.调用父类变量
有时候,父类的变量被子类覆盖了,此时想要访问父类的变量。实例:
class Animal{
int total_num = 20;
}
class Cat extends Animal{
int total_num = 10;
void getTotalNum() {
System.out.println("Animalt的总数量:"+super.total_num);
System.out.println("Cat的总数量:"+total_num);
}
}
public class Test {
public static void main(String[] args){
Cat cat1 = new Cat();
cat1.getTotalNum();
}
}
----------------------------------------------
输出结果:
Animalt的总数量:20
Cat的总数量:10
3.调用父类构造器
其实所有的构造器,第一行都调用了父类的构造器super(),实例:
class Animal{
Animal(){
System.out.println("父类构造器");
}
}
class Cat extends Animal{
Cat(){
//super(); 相当于这里有这句程序
System.out.println("子类构造器");
}
}
public class Test {
public static void main(String[] args){
new Cat();
}
}
-------------------------------------------
输出结果:
父类构造器
子类构造器
supper调父类构造方法,和this调子类重写的构造方法一样,必须放在第一行。所有supper调父类构造方法,和this调子类重写的构造方法不能一起使用。
再来一个,调用带参数的父类构造器实例:
class Animal{
private String name;
private int age;
Animal(String name,int age){
System.out.println("一位新动物出生了,名叫:"+name+"年龄:"+age);
}
}
class Cat extends Animal{
private String name;
private int age;
Cat(String name,int age){
super(name,age); /*注意,如果这里不屑调用带参数的父类构造器,那么会自动加上super(),来调用不带参数的父类构造器
但此时,父类Animal声明了一个带参数的构造器,系统就不会再自动生成不带参数的构造器
导致无法调用到不带参数的父类构造器,而报错*/
System.out.println("一只新小猫出生了,名叫:"+name+"年龄:"+age);
}
}
public class Test {
public static void main(String[] args){
new Cat("小猪",18);
}
}
---------------------------
输出结果:
一位新动物出生了,名叫:小猪年龄:18
一只新小猫出生了,名叫:小猪年龄:18