this 和 super
一、this 和 super
关键字this,在java中是当前对象的默认引用。它总是指向调用方法的对象,但是它代表的对象是不确定的,可是类型是确定的,即它所代表的对象只能是当前类。
在“疯狂Java讲义”(李刚著),我找到了this能被使用的缘由并做了一些自己的猜测。“当系统开始执行构造器的执行体之前,系统已经创建了一个对象,只是这个对象还不能被外部程序访问,只能在该构造器中通过this引用它。当构造器的执行体执行结束后,这个对象作为构造器的返回值被返回,通常还会赋给另外一个引用类型的变量,从而让外部程序可以访问该对象”。鉴于红色的那句话,我们并不奇怪为什么我们可以不用创建对象就能轻松地在构造器中甚至方法里访问对象属性(非类的属性)。关于这个隐藏对象的内容,个人猜测只有对象的属性和方法吧,因为它并不是用于产生对象,所以构造器就没有存在的必要。因此,在同个类里,某一方法访问另一方法只需this.方法名。(简略this也可,此处就不另作说明)
关键字super,在java中是父类对象的引用。子类继承父类,如果父类未初始化,就会初始化父类(也许这就是“孝”),于是父类就有了个隐藏的对象(完整地初始化父类对象),所以我们就能通过super轻松的获取父类的属性,甚至调用父类的构造器。
二、this和super的异同点
相同点
1、调用构造器“一”的原则。 为了提高代码的复用及方便维护,二者都是可以在某一构造器中调用另一构造器,但是this或super语句必须放在第一句(为什么强制放在第一行,个人暂不得其解),且不能用类名替换this或super,因为“A constructor can only be called in conjunction with the new operator.”(Java核心技术卷1:基础知识),从侧面也可以证明this对象中没有构造器。
2、区别同名属性。 因为this、super的定义,使得程序可以轻松区别同名的临时变量、实例属性、父类属性。使编译器不迷惑,程序更加健壮
不同点
1、针对相同点的1,如果在构造器中没有显示地使用this重载构造器,那么并不存在默认调用默认的无参构造器,所以也可以证明了当一个类存在有参构造时,如果你没有显示编出无参构造,那么这个类只有有参构造。 但是在子类的构造器调用父类的构造器,父类存在无参构造时,如果没有显示地使用super,系统会默认调用父类的无参构造初始化父类。
如果父类只存在有参构造,那么子类必须定义一个有参构造器,便于使用super使得父类的有参构造可以寄生在子类的有参构造中完成父类的初始化(看懂这段,需要补充类的初始化的知识点:...--> 父类初始化 -->子类初始化...)
为了不让看者继续迷惑,先贴出上述代码。代码中的英文其实很简单,如果存在语法错误,请见谅
相关代码:
package com.Inheritance;
/**************************************************
* separate from this to super
* @author: 瘋叻ハ.兩
* @revision: 1.0
* @create-time: 2011-9-6 上午12:48:53
*
* 序号①②对应上文总结的的知识点
* 如果要一一测试相应的知识点,请自行复制注释某几行代码个人测试。这里就不作说明
***************************************************/
public class ThisAndSuper {
public static void main(String[] args) {
System.out.println("test keyword this \n" );
Employees em = new Employees("John", 25, 5000);
System.out.println("-------------------------------------------");
System.out.println("test keyword super \n");
Managers ma = new Managers("Mike", 27, 4000);
}
}
class Employees{
private String name;
private int age;
public int salary; // public, just for testing conveniently
// default construction --> you must write out if you define another construction or it will be lost
public Employees(){
System.out.println("invoke superclass constructor without fields");
}
// define the construction with initializing all the fields
public Employees(String name, int a, int s){
this(); // 相同点的①、it's the correct way to overload default construction! if you annotate, it doesn't print sentence
this.name = name; // 相同点的②、you can identify temporal variable and object's variable clearly even though they are in the same name
this.age = a;
this.salary = s;
//this(); // it's the wrong way
System.out.println("invoke superclass construtor with fields");
}
}
class Managers extends Employees{
private int bonus;
// ①you can annotate to test because superclass has default constructor
public Managers(){
System.out.println("invoke subclass constructor without fields");
}
// 不同点的①、if superclass doesn't have default constructor, you can't annotate this constructor
// you can run the program without annotating any code to get obvious result
public Managers(String n, int a,int s){
super(n,a,s); // pay attention to the superclass constructor with fields
bonus = 0;
System.out.println("invoke subclass constructor with fields");
}
public void setBonus(int bonus){
this.bonus = bonus;
}
public int getSalary(){
int salary = super.salary; // the same as keyword this
return salary + bonus;
}
}
运行结果:
test keyword this
invoke superclass constructor without fields
invoke superclass construtor with fields
-------------------------------------------
test keyword super
invoke superclass constructor without fields
invoke superclass construtor with fields
invoke subclass constructor with fields
分 析 : 耐心看代码注释。
代码很杂,但是如果一一解释,太浪费空间。
2、this可以作为返回值,但是super不行
相关代码:
package com.Inheritance;
/**************************************************
* whether can return this or super
* @author: 瘋叻ハ. 兩
* @revision: 1.0
* @create-time: 2011-9-6 下午02:01:45
***************************************************/
class A{
public void getA(){
}
}
public class ReturnTest extends A{
private int a;
public A getClasses(){
return this;
// return super // it's wrong to change to return super
}
public void getA(){
a++;
System.out.println(a);
}
public static void main(String[] args){
// Polymorphism
new ReturnTest().getClasses().getA();
}
}
运行结果:
1
分析 :创建ReturnTest对象,调用getClasses( )返回的还是ReturnTest对象,所以可以使用getA( )方法。
希望本篇对于你区别this和super有点小小的收获。有不同意见的,不吝赐教!