this关键字与super关键字

一:this关键字.

1.1.为什么要用this引用?

看this之前先看一个代码:

public class Student{
	private String name;
	private String gender;
	private int age;
	//a.形参名不小心与成员变量名相同,函数体到底给谁赋值?
	public void setInfor(String name,String gender,int age){
		name=name;
		gender=gender;
		age=age;
	}
	public void printInfor(){
		System.out.println("name 是:"+name+",gender是:"+gender+",age是:"+age);
	}
	public static void main(String[] args){
		Student s1=new Student();
		Student s2=new Student();
		/*
			b.两个对象都在调用setInfor和printInfor方法,
				但是两个方法中没有任何有关对象的说明,
				setInfor和printInfor方法如何知道打印的是哪个对象的数据呢?
		*/
		s1.setInfor("wang","男",21);
		s2.setInfor("zhang","女",20);

		s1.printInfor();
		s2.printInfor();
	}
}

这个时候就需要使用this引用了.

1.2.什么是this关键字.

其实,java编译器给每个“成员方法“增加了一个隐藏的引用类型参数,该引用参数指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

public class Student{
	private String name;
	private String gender;
	private int age;
	public void setInfor(String name,String gender,int age){
		/*
			this.name指的就是Student类中的name成员变量方法.
			this.name=name语句中第二个name则指的是形参name
			实际上setInfor()方法实现的功能就是将name的值赋值给成员变量name.
		*/
		this.name=name;
		this.gender=gender;
		this.age=age;
	}
	public void printInfor(){
		System.out.println("name 是:"+this.name+",gender是:"+this.gender+",age是:"+this.age);
	}
}

this引用是编译器自动添加的,用户在实现代码时一般不需要显式给出.
注意:this引用的是调用成员方法的对象.

public static void main(String[] args) {
 	Student s = new Student();
 	s.setInfor("wang","男",21);
 	s.printDate();
}

1.3.this引用的特性.

a. this的类型:对应类类型引用,即哪个对象调用就是哪个对象的引用类型
b. this只能在"成员方法"中使用
c. 在"成员方法"中,this只能引用当前对象,不能再引用其他对象,具有final属性
d. this是“成员方法”第一个隐藏的参数,编译器会自动传递,在成员方法执行时,编译器会负责将调用成员方法
对象的引用传递给该成员方法,this负责来接收.

二.super关键字.

2.1super关键字的产生

在设计程序时,子类和父类中可能会存在相同名称的成员,如果在子类的方法中访问父类同名成员时,改如何操作?直接访问肯定是无法做到的,在此,Java提供了super关键字.

2.2 super关键字的使用.

2.2.1 调用成员方法和成员变量

创建父类.

public class Base(){
	int a;
	int b;
	public void methodA(){
		System.out.println("Base---methodA()");
	}
	public void methodB(){
		System.out.println("Base---methodB()");
	}
}

用子类进行继承

public class Derived extends Base{
	int a;
	char b;
	//与父类中的methodA构成重载
	public void methodA(int a){
		System.out.println("Derived---methodA(int)");
	}
	//与父类中的methodB构成重写
	public void methodB(){
		System.out.println("Derived---methodB()");
	}
	public void methodC(){
		//本类中的成员
		a=100;
		b=101;
		//super关键字调用父类中的成员
		super.a=200;
		super.b=201;
		
		methodA(100);		//调用子类中的methodA()方法,有参数
		methodA();			//从父类中继承的methodB()方法,无参数
		
		methodB();			//默认调用子类中的methodB()方法,无参
		//这里如果写methodB(),肯定会调用子类自己的方法.
		super.methodB();	//用super.调用父类中的methodB()方法
	}
	public class void main(String[] args){
		Derived d=new Derived ();
		d.methodC();
		/*
			输出结果:
			Derived---methodA(int)
			Base---methodA()
			Derived---methodB()
			Base---methodB()
		*/
	}
}

在子类方法中或者子类对象访问成员时,优先访问自己的,自己没有时再到父类中找,如果父类中也没有则报错。
注意:只能在非静态的方法中使用.

//编译时会报错.
public static void error(){
	super.a=300;
	super.methodA();
}

2.2.2调用构造方法.

子类对象构造时,需要先调用父类的构造方法,然后执行子类的构造方法.(这句话其实不严谨),先看代码,后文中解释.

public class Base{
	public Base(){
		System.out.println("Base()");
	}
}

子类继承父类.

public class Derived extends Base{
 	public Derived(){
 	// super();
 	/*
		注意:子类构造方法中默认会调用基类的无参构造方法:super(),
 	 	用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,
 	 	并且只能出现一次.
	*/
 		System.out.println("Derived()");
 }
}

测试类

public class Test {
 	public static void main(String[] args) {
 	Derived d = new Derived();
 	}
 	//运行结果
 	Base()
 	Derived()
}

从运行结果来看,确实是父类构造方法先于子类构造方法执行.
其实,创建对象的时候,先调用的是子类的构造方法,但是子类的构造方法中会用super()调用父类中的无参构造方法,并且永远处于第一行.所以运行结果会出现
先Base(),再Derived().

三 this和super的异同

3.1 相同点

a. 都是Java中的关键字
b. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
c. 在构造方法中调用时,必须是构造方法中的第一条语句,所以它两不能同时存在

3.2 不同点

a.this是当前对象的引用,当前对象即调用实例方法的对象,super相当于是父类对象的引用.
b.在非静态成员方法中,this用来访问本类的方法和属性,super用来访问父类继承下来的方法和属性.
c. this是非静态成员方法的一个隐藏参数,super不是隐藏的参数
d.成员方法中直接访问本类成员时,编译之后会将this还原,即本类非静态成员都是通过this来访问的;在子类中如果通过super访问父类成员,编译之后在字节码层面super实际是不存在的(通过字节码文件可以验证).
e.在构造方法中:this(…)用于调用本类构造方法,super(…)用于调用父类构造方法,两种调用不能同时在构造方法中出现.
f. 构造方法中一定会存在super(…)的调用,用户没有写编译器也会增加,但是this(…)用户不写则没有.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

感冒不能喝咖啡!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值