this关键字与super关键字

我们为什么需要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
发布了18 篇原创文章 · 获赞 0 · 访问量 413

猜你喜欢

转载自blog.csdn.net/HhmFighting/article/details/104867592