Java_多態

概念:

百度百科:

多態(Polymorphism)按字面的意思就是“多種狀態”。在面嚮對象語言中,接口的多種不同的實現方式即爲多態。

允許將子類類型的指針賦值給父類類型的指針。

作用:

把不同的子類對象都當作父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,以適應需求的不斷變化。

特性:

賦值之後,父類型的引用就可以根據當前賦值給它的子對象的特性以不同的方式運作。也就是說,父親的行爲像兒子,而不是兒子的行爲像父親。

簡而言之:編譯看左邊,運行看右邊

說明:

A a = new A();

一個對象是類的一個實例

這裏new A()纔是創建了一個對象,而a只是一個指向這個對象的一個引用(可以理解爲指針)

舉例:

Father類

public class Father {
	//父親的方法show()供兒子們繼承
	public void show() {
		System.out.println("I am a father. I have two sons.");
	}
	//父親獨有的方法somking()
	public void smoking() {
		System.out.println("A cigarette after dinner");
	}
}

Son1類繼承了Father

public class Son1 extends Father{
	//Son1繼承父親的方法show()
	public void show() {
		System.out.println("I'm a big brother Son1");
	}
	//Son1獨有的方法do_homework()
	public void do_homework() {
		System.out.println("Son1 doing homework");
	}
}

Son2類繼承了Father

public class Son2 extends Father{
	//Son2繼承父親的方法show()
	public void show() {
		System.out.println("I'm a little brother Son2");
	}
	//Son2獨有的方法play_game()
	public void play_game() {
		System.out.println("Son2 Playing games");
	}
}

主函數

public class Polymorphism_main {

	public static void main(String[] args) {
		//父類引用指向子類對象,此時子類會向上轉型成父類
		Father father1 = new Son1();
		Father father2 = new Son2();
		
		//此時father1和father2都是Father類型的引用(指針),但是指向的是子類Son1和Son2對象
		//編譯時看左邊Father類中有沒有show()方法,運行時看右邊Son1,Son2類中有沒有重寫show()方法
		//有重寫則調用Son1和Son2中的show()方法
		father1.show();
		father2.show();
		//這裏Son1,Son2中沒有對Father的smoking()進行重寫,所以會調用Father中的smoking()方法
		//子類會繼承父類的非私有方法
		father1.smoking();
		father2.smoking();
		
	}

}

結果

I'm a big brother Son1
I'm a little brother Son2
A cigarette after dinner
A cigarette after dinner

如果father1和father2這兩個父類引用調用子類Son1,Son2獨有的方法

//如果父類引用調用子類對象的獨有的方法
//編譯時看左邊Father中有沒有do_homework()方法,這裏會報“沒有爲Father定義方法do_homework()”的錯誤
//注意:這裏father1引用(指針)指向的是Son1的一個對象所以在對象創建(數據存儲)過程中包含了所有Son1的變量和方法
//只不過這個引用(指針)的類型是Father所以不能調用Son1獨有的方法
//father1.do_homework();
//father2.play_game();
		
//如果想調用子類獨有的方法,則需要強制向下轉型
//這裏son1只是把Father類型的引用(指針)father1重新定義爲Son1類型的引用(指針)
//因爲father1指向的是Son1的一個對象,這個對象在創建的時候肯定包含了Son1的所有變量和方法
//這裏只不過是把引用(指針)的類型重新定義爲Son1
Son1 son1 = (Son1)father1;
son1.do_homework();
		
Son2 son2 = (Son2)father2;
son2.play_game();

結果

Son1 doing homework
Son2 Playing games

那麼能不能子類引用指向父類對象呢?

//這裏直接寫會報類型不匹配的錯誤
//Son1 son1 = new Father();
//那麼如果進行強制轉換的話,編譯的時候不會報錯
//但運行的時候會報"Polymorphism.Father cannot be cast to Polymorphism.Son1"的異常
//因爲這裏是不安全的Father中不一定包含了Son1的所有變量和方法
//比如這裏Son1中的do_homework()方法則不包含
Son1 son1 = (Son1)new Father();
//注意:當創建一個子類對象時指向這個對象的引用(指針)可以是這個子類類型或者是這個子類的父類類型,
//但是如果創建的是一個父類對象則指向這個對象的引用(指針)就不能用這個父類的子類類型的指針來指向

總結:

父類引用指向子類對象

Father father = new Son()

創建這個子類對象的時候內存中肯定包含了所有父類的變量和方法,因爲子類繼承了父類的所有非私有的變量和方法

所以用father引用Father中方法的時候在內存中是存在父類的方法的,又因爲這裏創建的是子類的對象所以內存中還包含了子類的所有獨有變量和方法,只不過是使用Father類型的指針指向的,所有不能使用子類獨有的方法,但是如果重新定義指針的類型即Son son = (Son) father,把指針類型定義成子類的類型就可以使用子類獨有的方法了。

子類引用指向父類對象

Son son = new Father()

創建這個父類對象的時候,內存中只有該父類的所有變量和方法沒有子類的,因爲父類不能繼承子類的非私有變量和方法

所以當用這個子類引用son使用某個父類對象中沒有而子類對象中獨有的方法的時候就會出現內存中找不到該方法的情況,是不安全的

當創建一個子類對象時指向這個對象的引用(指針)可以是這個子類類型或者是這個子類的父類類型,
但是如果創建的是一個父類對象則指向這個對象的引用(指針)就不能用這個父類的子類類型的指針來指向

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章