摘要:多態(tài)性面向?qū)ο笕筇匦苑庋b繼承多態(tài)。面向?qū)ο蠖鄳B(tài)性存在的三個必要條件繼承重寫父類引用指向子類對象多態(tài)性的實現(xiàn)方式重寫與重載靜態(tài)多態(tài)性方法重載方法重載允許類具有多個相同名稱的方法,但是方法參數(shù)列表不同。
多態(tài)性
面向?qū)ο螅∣OP)三大特性:封裝、繼承、多態(tài)。
多態(tài)性(polymorphism)指同一行為具有多種不同表現(xiàn)形式,在面向?qū)ο蟪绦蛟O計中表現(xiàn)為同一消息可以根據(jù)發(fā)送對象的類型不同,做出多種不同的行為。
多態(tài)性的優(yōu)點
多態(tài)性能夠從一定程度上消除類型之間的耦合關系,通過統(tǒng)一接口方式,不同類的對象可以直接替換,程序更加靈活,可擴展。
面向?qū)ο蠖鄳B(tài)性存在的三個必要條件
繼承
重寫
父類引用指向子類對象
多態(tài)性的實現(xiàn)方式 重寫(Override)與重載(Overload) 靜態(tài)多態(tài)性:方法重載(Method Overloading)方法重載(Method Overloading)允許類具有多個相同名稱的方法,但是方法參數(shù)列表不同。
重載形式:
case 1: 參數(shù)數(shù)量變化(有效)
add(int, int) add(int, int, int)
case 2: 參數(shù)數(shù)據(jù)類型變化(有效)
add(int, int) add(int, float)
case 3: 參數(shù)數(shù)據(jù)類型順序變化(有效)
add(int, float) add(float, int)
bad case 1: 僅改變返回類型(無效)
int add(int, int) float add(int, int)
Java 方法簽名由方法名稱和其后的參數(shù)列表共同決定,僅改變返回類型編譯器無法重載。 不過方法重載(Method Overloading)允許改變返回類型和存取權(quán)限,但兩者不屬于方法簽名。
方法重載(Method Overloading)式多態(tài)性,即方法調(diào)用取決于調(diào)用時傳遞的參數(shù)(數(shù)量、類型、順序),屬于編譯時靜態(tài)多態(tài)性。
動態(tài)多態(tài)性:方法重寫(Method Overriding)方法重寫(Method Overriding)允許子類對父類可以訪問的方法,實現(xiàn)自定義行為,但是方法簽名需要保持一致。重寫的優(yōu)點在于,無需修改父類代碼即可改變子類繼承的方法。
重寫形式:
重寫依賴繼承,通過父類引用,指向子類對象實現(xiàn)動態(tài)多態(tài)性。
public class Animal{ public void sound(){ System.out.println("Animal is making a sound"); } } public class Cat extends Animal{ @Override public void sound(){ System.out.println("Meow"); } public static void main(String args[]){ Animal obj = new Cat(); obj.sound(); } }
輸出:
Meow
重寫(覆蓋)規(guī)則:
方法簽名(方法名稱和參數(shù)列表)必須一樣,返回類型需要兼容。
不能降低方法的存取權(quán)限。
static, private, final 標記的方法以及類的構(gòu)造方法不能被重寫(覆蓋)。
分析原因:
Java 通過方法簽名標識方法,因此重寫需要確保是子類繼承自父類的同一方法。
子類不可以降低父類方法的存取權(quán)限(可見性),但可以升級。繼承反映一種 “is a” 關系,子類是父類,支持父類所有對外開放的行為。降低方法的存取權(quán)限,使得父類作為統(tǒng)一接口方式調(diào)用方法的能力被破壞。
private, final 標記的方法以及父類的構(gòu)造方法無法繼承,故無法重寫。
static 標記的方法為靜態(tài)方法屬于類,通過類名.方法名形式調(diào)用,無需依賴對象。
靜態(tài)方法和屬性會被子類繼承,子類同樣允許定義同名靜態(tài)方法和屬性,區(qū)別于實例方法“重寫”和屬性“重名”,這種情況被稱為“隱藏”。此時子類中調(diào)用同名的父類靜態(tài)方法和屬性,需要指明父類名.方法名或父類名.變量名。
多態(tài)性的類型可以分為運行時和編譯時,方法重寫(Method Overriding)代表運行時動態(tài)多態(tài)性,方法重載(Method Overloading)代表編譯時靜態(tài)多態(tài)性。
方法調(diào)用與方法體的關聯(lián)稱為綁定,有兩種類型的綁定:在編譯時發(fā)生的靜態(tài)綁定(Static Binding or Early Binding)和在運行時發(fā)生的動態(tài)綁定(Dynamic Binding or Late Binding)。
static, private, final 標記的方法以及類的構(gòu)造方法是靜態(tài)綁定的,在編譯時確定所屬類的類型,因此這些方法無法覆蓋。其他非標記的方法可以稱為“虛函數(shù)”,Java 中其實并沒有“虛函數(shù)”的概念,所有普通函數(shù)(方法)默認都相當于 C++ 的”虛函數(shù)”允許覆蓋(Override),因此虛函數(shù)(Virtual Method)能夠根據(jù)運行時具體對象的類型進行動態(tài)綁定實現(xiàn)動態(tài)多態(tài)性,例如方法重寫(Method Overriding)。
靜態(tài)綁定示例:
class Human{ public static void walk() { System.out.println("Human walks"); } } class Boy extends Human{ public static void walk(){ System.out.println("Boy walks"); } public static void main( String args[]) { /* Reference is of Human type and object is * Boy type */ Human obj = new Boy(); /* Reference is of Human type and object is * of Human type. */ Human obj2 = new Human(); obj.walk(); obj2.walk(); } }
輸出:
Human walks Human walks
聲明為 static 的方法不能被重寫,但是能夠被再次聲明(隱藏)。
Static Binding vs Dynamic Binding
靜態(tài)綁定發(fā)生在編譯時,而動態(tài)綁定發(fā)生在運行時。
靜態(tài)綁定使用的是類信息:類的類型決定調(diào)用方法,而動態(tài)綁定使用的是對象信息:對象的類型決定調(diào)用方法。
方法重載使用靜態(tài)綁定,而方法重寫使用動態(tài)綁定。
綜合練習多態(tài)性示例程序:
class A { public String show(D obj) { // 方法一 return ("A and D"); } public String show(A obj) { // 方法二 return ("A and A"); } } class B extends A { public String show(B obj) { // 方法三 return ("B and B"); } public String show(A obj) { // 方法四 return ("B and A"); } } class C extends B { } class D extends B { } public class Main { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println("1--" + a1.show(b)); System.out.println("2--" + a1.show(c)); System.out.println("3--" + a1.show(d)); System.out.println("4--" + a2.show(b)); System.out.println("5--" + a2.show(c)); System.out.println("6--" + a2.show(d)); System.out.println("7--" + b.show(b)); System.out.println("8--" + b.show(c)); System.out.println("9--" + b.show(d)); } }
運行結(jié)果:
1--A and A 2--A and A 3--A and D 4--B and A 5--B and A 6--A and D 7--B and B 8--B and B 9--A and D
詳細分析:
A、B、C、D 各類繼承關系如圖所示:
A a1 = new A(); 正常創(chuàng)建對象 a1,涉及函數(shù)重載 show(),a1 具有調(diào)用方法一 show(D obj) 和方法二 show(A obj) 的能力。
a1.show(b) 由編譯器進行靜態(tài)綁定(前期綁定)方法二 show(A obj)。
a1.show(c) 由編譯器進行靜態(tài)綁定(前期綁定)方法二 show(A obj)。
a1.show(d) 由編譯器進行靜態(tài)綁定(前期綁定)方法一 show(D obj)。
A a2 = new B(); 多態(tài)創(chuàng)建父類引用,指向子類對象,a2 向上轉(zhuǎn)型具有調(diào)用 A 類方法一 show(D obj) 和方法二 show(A obj) 的能力,其中子類 B 重寫父類 A 的方法二 show(A obj) 為方法四 show(A obj)。記住向上轉(zhuǎn)型存在缺點,即不能調(diào)用子類中有,父類沒有的方法,如方法三 show(B obj)。
a2.show(b) 運行時動態(tài)綁定(后期綁定)方法四 show(A obj)。
a2.show(c) 運行時動態(tài)綁定(后期綁定)方法四 show(A obj)。
a2.show(d) 由編譯器進行靜態(tài)綁定(前期綁定)方法一 show(D obj)。
B b = new B(); 正常創(chuàng)建對象 b,涉及函數(shù)重載 show(),b 具有調(diào)用方法三 show(B obj) 和方法四 show(A obj) 的能力。同時 B 繼承自 A 因此擁有方法一 show(D obj) 和方法二 show(A obj) 其中方法二被方法四重寫覆蓋。
b.show(b) 由編譯器進行靜態(tài)綁定(前期綁定)方法三 show(B obj)。
b.show(c) 由編譯器進行靜態(tài)綁定(前期綁定)方法三 show(B obj)。
b.show(d) 由編譯器進行靜態(tài)綁定(前期綁定)方法一 show(D obj)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/71578.html
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:很多情況下,通常一個人類,即創(chuàng)建了一個具體的對象。對象就是數(shù)據(jù),對象本身不包含方法。類是相似對象的描述,稱為類的定義,是該類對象的藍圖或原型。在中,對象通過對類的實體化形成的對象。一類的對象抽取出來。注意中,對象一定是通過類的實例化來的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 馬上就要到七夕了,離年底老媽老爸...
摘要:方法即為收集器,它接收高階函數(shù)和的后端掘金年的第一天,我坐在獨墅湖邊,寫下這篇文章。正因如此,所以最全系列教程后端掘金是從版本開始引入的一個新的,可以替代標準的。 設計模式之單例模式 - 掘金前言 作為一個好學習的程序開發(fā)者,應該會去學習優(yōu)秀的開源框架,當然學習的過程中不免會去閱讀源碼,這也是一個優(yōu)秀程序員的必備素養(yǎng),在學習的過程中很多人會遇到的障礙,那就是設計模式。很多優(yōu)秀的框架會運...
閱讀 1639·2021-11-04 16:11
閱讀 3363·2021-09-09 11:33
閱讀 1611·2019-08-30 15:54
閱讀 641·2019-08-30 15:44
閱讀 3210·2019-08-30 15:43
閱讀 2589·2019-08-30 13:06
閱讀 1724·2019-08-29 17:00
閱讀 923·2019-08-29 15:33