㈠ java中多態性什麼意思
多態性:顧名思義就是擁有「多種形態」的含義,是指屬性或方法在子類中表現為多種形態。
在JAVA中有兩種多態是指:運行時多態和編譯時多態。多態性是面向對象的核心特徵之一,類的多態性提供類中成員設計的靈活性和方法執行的多樣性。
多態指允許不同類的對象對同一消息做出響應。即同一消息可以根據發送對象的不同而採用多種不同的行為方式。(發送消息就是函數調用)
實現多態的技術稱為:動態綁定(dynamic binding),是指在執行期間判斷所引用對象的實際類型,根據其實際的類型調用其相應的方法。
擴展資料:
多態的好處:
1、可替換性(substitutability)多態對已存在代碼具有可替換性。例如,多態對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
2、可擴充性(extensibility)多態對代碼具有可擴充性。增加新的子類不影響已存在類的多態性、繼承性,以及其他特性的運行和操作。實際上新加子類更容易獲得多態功能。
3、介面性(interface-ability)多態是超類通過方法簽名,向子類提供了一個共同介面,由子類來完善或者覆蓋它而實現的。
4、靈活性(flexibility)它在應用中體現了靈活多樣的操作,提高了使用效率。
5、簡化性(simplicity)多態簡化對應用軟體的代碼編寫和修改過程,尤其在處理大量對象的運算和操作時,這個特點尤為突出和重要。
㈡ 誰能跟我說幾個JAVA多態,在現實生活中應用的例子,不要說代碼和概念,就只說案例
有一個比較經典的多態實例:有一個Animal類,它有Cat,和Dog兩個子類,在Animal中有個say方法,當Cat調用這個方法的時候輸出的是「小貓喵喵喵」,這就是Java多態的實現。
1、定義一種動物,該類型的動物有叫的屬性。
2、分別定義貓,狗,鳥,都繼承於該動物,都有叫的屬性。
3、分別表示出各個具體小動物的叫聲,例如貓的叫聲:喵、狗的叫聲:汪、鳥的叫聲:咻,點是叫聲,實現各個具體小動物用的叫聲的方法是用的同一個函數名稱,就是動物的叫聲函數。
JRE
是個運行環境,JDK是個開發環境。因此寫Java程序的時候需要JDK,而運行Java程序的時候就需要JRE。而JDK裡面已經包含了JRE,因此只要安裝了JDK,就可以編輯Java程序,也可以正常運行Java程序。但由於JDK包含了許多與運行無關的內容,佔用的空間較大,因此運行普通的Java程序無須安裝JDK,而只需要安裝JRE即可。
㈢ 談談你對Java中的多態的理解.(為什麼要使用多態,有什麼好處,一般用在什麼場合)
面向對象編程有三大特性:封裝、繼承、多態。
封裝隱藏了類的內部實現機制,可以在不影響使用的情況下改變類的內部結構,同時也保護了數據。對外界而已它的內部細節是隱藏的,暴露給外界的只是它的訪問方法。
繼承是為了重用父類代碼。兩個類若存在IS-A的關系就可以使用繼承。,同時繼承也為實現多態做了鋪墊。
那麼什麼是多態呢?多態的實現機制又是什麼?請看我一一為你揭開:
所謂多態
就是指程序中定義的引用變數所指向的具體類型和通過該引用變數發出的方法調用在編程時並不確定,而是在程序運行期間才確定,即一個引用變數倒底會指向哪個類的實例對象,該引用變數發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。因為在程序運行時才確定具體的類,這樣,不用修改源程序代碼,就可以讓引用變數綁定到各種不同的類實現上,從而導致該引用調用的具體方法隨之改變,即不修改程序代碼就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態,這就是多態性。
比如你是一個酒神,對酒情有獨鍾。某日回家發現桌上有幾個杯子裡面都裝了白酒,從外面看我們是不可能知道這是些什麼酒,只有喝了之後才能夠猜出來是何種酒。你一喝,這是劍南春、再喝這是五糧液、再喝這是酒鬼酒….在這里我們可以描述成如下:
酒 a = 劍南春
酒 b = 五糧液
酒 c = 酒鬼酒
…
這里所表現的的就是多態。劍南春、五糧液、酒鬼酒都是酒的子類,我們只是通過酒這一個父類就能夠引用不同的子類,這就是多態——我們只有在運行的時候才會知道引用變數所指向的具體實例對象。
誠然,要理解多態我們就必須要明白什麼是「向上轉型」。在繼承中我們簡單介紹了向上轉型,這里就在啰嗦下:在上面的喝酒例子中,酒(Win)是父類,劍南春(JNC)、五糧液(WLY)、酒鬼酒(JGJ)是子類。我們定義如下代碼:
JNC a = new JNC();
對於這個代碼我們非常容易理解無非就是實例化了一個劍南春的對象嘛!但是這樣呢?
Wine a = new JNC();
在這里我們這樣理解,這里定義了一個Wine 類型的a,它指向JNC對象實例。由於JNC是繼承與Wine,所以JNC可以自動向上轉型為Wine,所以a是可以指向JNC實例對象的。這樣做存在一個非常大的好處,在繼承中我們知道子類是父類的擴展,它可以提供比父類更加強大的功能,如果我們定義了一個指向子類的父類引用類型,那麼它除了能夠引用父類的共性外,還可以使用子類強大的功能。
但是向上轉型存在一些缺憾,那就是它必定會導致一些方法和屬性的丟失,而導致我們不能夠獲取它們。所以父類類型的引用可以調用父類中定義的所有屬性和方法,對於只存在與子類中的方法和屬性它就望塵莫及了。
publicclassWine{
publicvoidfun1(){
System.out.println("Wine的Fun.....");
fun2();
}
publicvoidfun2(){
System.out.println("Wine的Fun2...");
}
}
publicclassJNCextendsWine{
/**
*@desc子類重載父類方法
*父類中不存在該方法,向上轉型後,父類是不能引用該方法的
*@parama
*@returnvoid
*/
publicvoidfun1(Stringa){
System.out.println("JNC的Fun1...");
fun2();
}
/**
*子類重寫父類方法
*指向子類的父類引用調用fun2時,必定是調用該方法
*/
publicvoidfun2(){
System.out.println("JNC的Fun2...");
}
}
publicclassTest{
publicstaticvoidmain(String[]args){
Winea=newJNC();
a.fun1();
}
}
-------------------------------------------------
Output:
Wine的Fun.....
JNC的Fun2...
從程序的運行結果中我們發現,a.fun1()首先是運行父類Wine中的fun1().然後再運行子類JNC中的fun2()。
分析:在這個程序中子類JNC重載了父類Wine的方法fun1(),重寫fun2(),而且重載後的fun1(String a)與 fun1()不是同一個方法,由於父類中沒有該方法,向上轉型後會丟失該方法,所以執行JNC的Wine類型引用是不能引用fun1(String a)方法。而子類JNC重寫了fun2() ,那麼指向JNC的Wine引用會調用JNC中fun2()方法。
所以對於多態我們可以總結如下:
指向子類的父類引用由於向上轉型了,它只能訪問父類中擁有的方法和屬性,而對於子類中存在而父類中不存在的方法,該引用是不能使用的,盡管是重載該方法。若子類重寫了父類中的某些方法,在調用該些方法的時候,必定是使用子類中定義的這些方法(動態連接、動態調用)。
對於面向對象而已,多態分為編譯時多態和運行時多態。其中編輯時多態是靜態的,主要是指方法的重載,它是根據參數列表的不同來區分不同的函數,通過編輯之後會變成兩個不同的函數,在運行時談不上多態。而運行時多態是動態的,它是通過動態綁定來實現的,也就是我們所說的多態性。
多態的實現
2.1實現條件
在剛剛開始就提到了繼承在為多態的實現做了准備。子類Child繼承父類Father,我們可以編寫一個指向子類的父類類型引用,該引用既可以處理父類Father對象,也可以處理子類Child對象,當相同的消息發送給子類或者父類對象時,該對象就會根據自己所屬的引用而執行不同的行為,這就是多態。即多態性就是相同的消息使得不同的類做出不同的響應。
Java實現多態有三個必要條件:繼承、重寫、向上轉型。
繼承:在多態中必須存在有繼承關系的子類和父類。
重寫:子類對父類中某些方法進行重新定義,在調用這些方法時就會調用子類的方法。
向上轉型:在多態中需要將子類的引用賦給父類對象,只有這樣該引用才能夠具備技能調用父類的方法和子類的方法。
只有滿足了上述三個條件,我們才能夠在同一個繼承結構中使用統一的邏輯實現代碼處理不同的對象,從而達到執行不同的行為。
對於Java而言,它多態的實現機制遵循一個原則:當超類對象引用變數引用子類對象時,被引用對象的類型而不是引用變數的類型決定了調用誰的成員方法,但是這個被調用的方法必須是在超類中定義過的,也就是說被子類覆蓋的方法。
2.2實現形式
在Java中有兩種形式可以實現多態。繼承和介面。
2.2.1、基於繼承實現的多態
基於繼承的實現機制主要表現在父類和繼承該父類的一個或多個子類對某些方法的重寫,多個子類對同一方法的重寫可以表現出不同的行為。
publicclassWine{
privateStringname;
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicWine(){
}
publicStringdrink(){
return"喝的是"+getName();
}
/**
*重寫toString()
*/
publicStringtoString(){
returnnull;
}
}
publicclassJNCextendsWine{
publicJNC(){
setName("JNC");
}
/**
*重寫父類方法,實現多態
*/
publicStringdrink(){
return"喝的是"+getName();
}
/**
*重寫toString()
*/
publicStringtoString(){
return"Wine:"+getName();
}
}
publicclassJGJextendsWine{
publicJGJ(){
setName("JGJ");
}
/**
*重寫父類方法,實現多態
*/
publicStringdrink(){
return"喝的是"+getName();
}
/**
*重寫toString()
*/
publicStringtoString(){
return"Wine:"+getName();
}
}
publicclassTest{
publicstaticvoidmain(String[]args){
//定義父類數組
Wine[]wines=newWine[2];
//定義兩個子類
JNCjnc=newJNC();
JGJjgj=newJGJ();
//父類引用子類對象
wines[0]=jnc;
wines[1]=jgj;
for(inti=0;i<2;i++){
System.out.println(wines[i].toString()+"--"+wines[i].drink());
}
System.out.println("-------------------------------");
}
}
OUTPUT:
Wine:JNC--喝的是JNC
Wine:JGJ--喝的是JGJ
在上面的代碼中JNC、JGJ繼承Wine,並且重寫了drink()、toString()方法,程序運行結果是調用子類中方法,輸出JNC、JGJ的名稱,這就是多態的表現。不同的對象可以執行相同的行為,但是他們都需要通過自己的實現方式來執行,這就要得益於向上轉型了。
我們都知道所有的類都繼承自超類Object,toString()方法也是Object中方法,當我們這樣寫時:
Objecto=newJGJ();
System.out.println(o.toString());
輸出的結果是Wine : JGJ。
Object、Wine、JGJ三者繼承鏈關系是:JGJ—>Wine—>Object。所以我們可以這樣說:當子類重寫父類的方法被調用時,只有對象繼承鏈中的最末端的方法才會被調用。但是注意如果這樣寫:
Objecto=newWine();
System.out.println(o.toString());
輸出的結果應該是Null,因為JGJ並不存在於該對象繼承鏈中。
所以基於繼承實現的多態可以總結如下:對於引用子類的父類類型,在處理該引用時,它適用於繼承該父類的所有子類,子類對象的不同,對方法的實現也就不同,執行相同動作產生的行為也就不同。
如果父類是抽象類,那麼子類必須要實現父類中所有的抽象方法,這樣該父類所有的子類一定存在統一的對外介面,但其內部的具體實現可以各異。這樣我們就可以使用頂層類提供的統一介面來處理該層次的方法。
2.2.2、基於介面實現的多態
繼承是通過重寫父類的同一方法的幾個不同子類來體現的,那麼就可就是通過實現介面並覆蓋介面中同一方法的幾不同的類體現的。
在介面的多態中,指向介面的引用必須是指定這實現了該介面的一個類的實常式序,在運行時,根據對象引用的實際類型來執行對應的方法。
繼承都是單繼承,只能為一組相關的類提供一致的服務介面。但是介面可以是多繼承多實現,它能夠利用一組相關或者不相關的介面進行組合與擴充,能夠對外提供一致的服務介面。所以它相對於繼承來說有更好的靈活性。
㈣ Java中的多態到底有什麼實際開發作用
JAVA語言特徵之一多態機制,故名思議就是多種變化形態。
在實際的開發當中一般都應用在兩個方面,其一:神段方法的多態---重載(overload)和重寫(override),其二:對象的多態,對象的向上轉型,對象的向下轉型。
方法的重載:發生在同一個類當中,方法名稱相同,參數列表不同。
經常看到的就是某一個類的構造方法,例如:String類
當然也可以是其他普通方法。
方法的重寫:發生在有繼承關系的類中(說白了就是子類中),方法名稱和參數列表一模一樣。
例如: Object類當中的equals()方法、toString()方法等。
對象的多態:
向上轉型: 父類類型 父類對象名稱 = new 子類類型();
向下轉型:子類類型 子類對象名稱 = (子類類型)父類對象名稱;
注意: 先由向上轉型再有向下轉型,如果直接寫向下轉型則會出現ClassCastException(類型轉換異常)
應用:1.為介面/抽象類實例化對象
例如: List<String> list = new ArrayList<String>();
2.在方法當中的參數----如果是父類類型,則可以傳入子類對象
謹腔 例如: public void show(Object obj) {}
6.當然,在高級框架中也是存在多游晌譽態的內容,但是只要知道怎麼用即可。