1. 程式人生 > >super和this的區別

super和this的區別

參考部落格:https://www.cnblogs.com/hasse/p/5023392.html

                  http://blog.csdn.net/zuoyang1990/article/details/53471494

this

this是自身的一個物件,代表物件本身,可以理解為:指向物件本身的一個指標。

this的用法在java中大體可以分為3種:

 1、普通的直接引用

/**
 * 當在一個類中明確指出使用物件自己的變數或函式時需加上this的引用
 *
 */
class Hello{
	String str = "hello";
	public Hello(String s){
		System.out.println("s = " + s);
		System.out.println("1 -> this.s = " + this.str);
		// 當在一個類中明確指出使用物件自己的變數或函式時需加上this的引用
		this.str = s;
		System.out.println("2 -> this.s = " + this.str);
	}
}

public class test1{
	
	public static void main(String[] args) {

		Hello h = new Hello("word");
		
		
	}

}

執行結果為:

s = word
1 -> this.s = hello
2 -> this.s = word

 2、形參與成員名字重名,用this來區分

class Hello1{
	String name = "hello";
	public void setName(String name){
		this.name = name;
	}
	
	public String getName(){
		return this.name;
	}
}


public class test2 {

	public static void main(String[] args) {

		Hello1 h = new Hello1();
		
		h.setName("word");
		System.out.println(h.getName());	
	}
}


執行結果為:

word

3、引用建構函式

這個和super放在一起講

super

super可以理解為指向自己超(父)類物件的一個指標,而這個超類指的是離自己最近的一個父類。

super也有三種用法

1、普通的直接引用

與this相似,super相當於是指向當前物件的父類,這樣就可以用super.xxx來引用父類的成員

class Animal{
	private String member1 = "member1";
	protected String member2 = "member2";
	public String member3 = "member3";
	String member4 = "member4";
	
	public Animal(){
		
	}
}

class Cat extends Animal{
	public Cat(){
		// System.out.println(super.member1); 不能訪問標為private的成員
		System.out.println(super.member2);
		System.out.println(super.member3);
		System.out.println(super.member4);//如果子類與父類在同一包內,可以訪問預設(無修飾符)的成員變數與方法。
	}
}

public class test3 {
	public static void main(String[] args) {
		Cat c = new Cat();
	}
}


執行結果為:

member2member3member4

2、子類中的成員變數或方法與父類中的成員變數或方法重名

class Animal{
	
	String name = "animals";
	void value(){
		name = "Animal";
	}
}

class Dog extends Animal{
	
	String name;
	void value(){
		name = "Dog";
		super.value();
		System.out.println(name);
		System.out.println(super.name);
	}
	
}
public class test4 {
	public static void main(String[] args) {
		Dog d = new Dog();
		d.value();
	}
}

執行結果:

Dog

Animal

可以看到,這裡既呼叫了父類的方法,也呼叫了子類的變數。若不呼叫父類方法value(),只調用父類變數name的話,則父類的name值為animals

3、引用建構函式

super(引數):呼叫父類中的某一個建構函式(應該為建構函式中的第一條語句)

this(引數):呼叫本類中另一種形式的建構函式(應該為建構函式中的第一條語句)

/**
 * super()函式在子類建構函式中呼叫父類的建構函式時使用,而且必須要在建構函式的第一行
 * 呼叫父類的方法
 */
class Animal{
	public Animal(){
		System.out.println("父類無參建構函式:An animal");
	}

	public Animal(String name){
		System.out.println("父類有參建構函式:"+name);
	}

	void getName(String name){
		System.out.println("父類:this is " + name);
	}
}
class Dog extends Animal{

	public Dog(){
		// super()函式在子類建構函式中呼叫父類的建構函式時使用,而且必須要在建構函式的第一行
		// 如果子類建構函式中沒有寫super()函式,編譯器會自動幫我們新增一個無引數的super()
		
		// 1、2、3、4只能選其一,且必須在建構函式第一行
		super();//1:呼叫父類無參建構函式
//		super("animals");//2:呼叫父類相應有參建構函式
//		
//		this();//3:呼叫子類本身的無參建構函式
//		this("animals");//4:呼叫子類本身相應的有參建構函式
		
		//super.getName("animals");//呼叫父類的方法
		this.getName("animals");//若子類重寫了此方法則呼叫子類本身的方法,若子類未重寫,則呼叫父類的方法
		System.out.println("A Dog");
	}
	
	void getName(String name){
		System.out.println("子類:this is " + name);
	}
}

public class Main {
	
	public static void main(String[] args) {
		Dog dog = new Dog();
	}

}

輸出結果為

父類無參建構函式:An animal
子類:this is animals
A Dog

super和this的異同:

1、super(引數):呼叫基類中的另一個建構函式(應該為建構函式的第一條語句)

2、this(引數):呼叫本類中另一種形式的建構函式(應該為建構函式的第一條語句)

3、super:它引用當前物件的直接父類中的成員(用來訪問直接父類中被隱藏的父類中成員資料或函式,基類與派生類中有相同成員定義時:super.變數名,super.成員函式資料名(實參))

4、this:它代表當前物件名(在程式中易產生二義性之處,應使用this來指明當前物件;如果函式的形參與類中的成員資料同名,這時需用this來指明成員變數名)

5、呼叫super()必須寫在子類構造方法的第一行,否則編譯不通過。每個子類構造方法的第一條語句,都是隱含地呼叫super(),如果父類沒有這種形式的建構函式,那麼在遍歷的時候就會報錯

6、super()和this()類似,區別是,super()從子類中呼叫父類的構造方法,this()在同一類內呼叫其它方法

7、super()和this()均需放在構造方法內第一行

8、儘管可以用this呼叫一個構造器,但卻不能呼叫兩個

9、this和super不能同時出現在一個建構函式裡面,因為this必然會呼叫其它的建構函式,其它的建構函式必然也會有super語句的存在,所以在同一個建構函式裡面有相同的語句,就失去了語句的意義,編譯器也不會通過

10、this()和super()都指的是物件,所以,均不可以在static環境中使用。包括static變數、static方法、static語句塊

11、從本質上講,this是一個指向本物件的指標,然而super是一個Java關鍵字