JAVA_SE基礎——48.多態

面向對象程序設計的三個特色是封裝繼承多態。前面已經學習了前兩個特色。本章節將介紹多態性。html


多態:一個對象具有多種形態。(父類的引用類型變量指向了子類的對象)或者是接口 的引用類型變量指向了接口實現類的對象)


多態的前提:必須存在繼承或者實現 關係。


    動物  a  = new   狗();
java


在多態中成員函數的特色:(針對非靜態成員函數) 
 
    在編譯時期:參閱引用型變量所屬的類中是否有調用的方法。若是有,編譯經過,若是沒有,編譯失敗 
 
    在運行時期,參閱對象所屬的類中是否有調用的方法 
    簡單總結就是:成員函數在多態中調用,編譯看左邊,運行看右邊 
 
    在多態中,成員變量的特色: 
    不管編譯仍是運行,都參考左邊(引用型變量所屬的類) 
 
    在多態中,靜態成員函數的特色: 
    不管編譯仍是運行,都參考左邊 
編程


多態的好處: 提升了代碼的拓展性。把不一樣的子類對象都看成父類來看,能夠屏蔽不一樣子類對象之間的差別,寫出通用的代碼,作出通用的編程,以適應需求的不斷變化。

函數

多態的應用一個對象具有了多種形態。 子類實現了父類後的對象,既是父類對象又是子類對象。

具體應用:轉型理解


向上轉型與向下轉型的理解


向上轉型:父類 F =new 子類()


向下轉型:子類 Z=new (子類)F


理解:


1.子類實現了父類後的對象,既是父類對象又是子類對象。因此能夠向下轉換。這也就是多態的體現點,多種形態。就是會說這個既是父類對象又是子類對象的對象。


 2.向下轉換後,就徹底變成子類,能夠調用子類的全部方法。  
學習


package day09;

class Fu{
	int num = 1;	//父類中的成員變量
	
	void method1(){
		System.out.println("fu類中的method1()方法");
	}
	
	void method2(){
		System.out.println("fu類中的method2()方法");
	}

	static void method4(){
		System.out.println("fu類中的method4()方法");
	}
}

class Zi extends Fu{

	int num = 2;
	
	void method1(){
		System.out.println("Zi類中的method1()方法");
	}

	void method3(){
		System.out.println("Zi類中的method3()方法");
	}

	static void method4(){
		System.out.println("Zi類中的method4()方法");
	}
}


class Demo9
{
	public static void main(String []args)
	{
		
		Fu f = new Zi();
		f.method1(); 
		f.method2();
		f.method4();	
		System.out.println(f.num);//1
		Zi z = new Zi();	
		System.out.println(z.num);//2
		z.method1();
		z.method2();
		z.method3();
		z.method4();
	}
}

運行結果:spa



我本身對多態的理解(不喜勿噴):子類有的,就用子類的,子類沒有的,就用父類的,子父類都沒有的,報錯。設計


根據上面代碼修改:在f.method4();  後面加句f.method3(); 

package day09;

class Fu{
	int num = 1;	//父類中的成員變量
	
	void method1(){
		System.out.println("fu類中的method1()方法");
	}
	
	void method2(){
		System.out.println("fu類中的method2()方法");
	}

	static void method4(){
		System.out.println("fu類中的method4()方法");
	}
}

class Zi extends Fu{

	int num = 2;
	
	void method1(){
		System.out.println("Zi類中的method1()方法");
	}

	void method3(){
		System.out.println("Zi類中的method3()方法");
	}

	static void method4(){
		System.out.println("Zi類中的method4()方法");
	}
}
class Demo9
{
	public static void main(String []args)
	{
		
		Fu f = new Zi();
		f.method1(); //Zi類中的method1()方法
		f.method2(); //fu類中的method2()方法
		f.method4(); //fu類中的method4()方法
		f.method3(); //這句是加上去的 
		System.out.println(f.num);//1
		Zi z = new Zi();	
		System.out.println(z.num);//2
		z.method1();
		z.method2();
		z.method3();
		z.method4();
	}
}
運行結果:


 

引用:code

 在編譯時期:參閱引用型變量所屬的類中是否有調用的方法。若是有,編譯經過,若是沒有,編譯失敗 
 
 在運行時期,參閱對象所屬的類中是否有調用的方法 
    簡單總結就是:成員函數在多態中調用,編譯看左邊,運行看右邊 
htm

----------------------------------------------------------------------------------------------對象

 代碼解釋:f.method3();    .f   是所屬Fu類的 ,,父類沒有這方法    因此編譯失敗。


如何理解這句話 :成員函數在多態中調用,編譯看左邊,運行看右邊   

意思就是:在編譯的時候編譯器無論你右邊是什麼類,只要左邊的Fu類(或接口)能編譯經過就不會報錯。可是運行的時候就要按照右邊的Zi()類實際狀況來運行。

當父類變量引用子類對象時(Fu fu = new Zi();),在這個引用變量 fu 指向的變量/方法中,他對成員變量和靜態方法的調用與父類是一致的,他調用非靜態方法時,在編譯時是與父類一致的(查看父類有沒有該函數,沒有就會發生編譯錯誤,提示fu 中找不到要調用函數),運行時若是子類中發生了複寫就與子類一致。(若是右邊沒有再看左邊。若都沒有才會報錯)


那爲什麼f.method3();     不能調用method3()方法呢 ?   

若是想要調用Zi類的特有方法,如何操做?
            強制將父類的引用,轉成子類類型。向下轉型(怎麼轉看下面的code1 。)
Zi x = (Zi)fu;
x.method3();
 在多態中,調用子類函數,子類方法必須覆蓋父類中的方法,若是調用子類特有的方法,就必須向下轉型了。這樣非靜態的方法可直接調用。


code1:

package day09;

class Fu{
	int num = 1;	//父類中的成員變量
	
	void method1(){
		System.out.println("fu類中的method1()方法");
	}
	
	void method2(){
		System.out.println("fu類中的method2()方法");
	}

	static void method4(){
		System.out.println("fu類中的method4()方法");
	}
}

class Zi extends Fu{

	int num = 2;
	
	void method1(){
		System.out.println("Zi類中的method1()方法");
	}

	void method3(){
		System.out.println("Zi類中的method3()方法");
	}

	static void method4(){
		System.out.println("Zi類中的method4()方法");
	}
}
class Demo9
{
	public static void main(String []args)
	{
		
		Fu f = new Zi();
		f.method1(); //Zi類中的method1()方法
		f.method2(); //fu類中的method2()方法
		f.method4(); //fu類中的method4()方法
		FuShout(f);
		System.out.println(f.num);//1
		Zi z = new Zi();	
		System.out.println(z.num);//2
		z.method1();
		z.method2();
		z.method3();
		z.method4();
	}
	//定義一個向下轉型的方法 。
	public static void FuShout(Fu fu){
		if(fu instanceof Fu){	//判斷fu是不是Fu類的實例對象
			Zi x = (Zi)			//將fu強轉爲Cat類型
			x.method3();		//調用Zi類特有的method3()方法
		}
	}
}


運行結果:



instanceof

Java提供了一個關鍵字instanceof,它能夠判斷一個對象是否爲某個類(或接口)的實例或者子類的實例。

格式:

對象(或者對象引用變量) instanceof 類(或接口)

相關文章
相關標籤/搜索