【威哥說】王健林一句話,刷爆了朋友圈喧务±蹈瑁“先定一個能達(dá)到的小目標(biāo),比方說我先掙它一個億”功茴。好吧俏站,也許我們沒有那樣的霸氣,至少我們可以實現(xiàn)這樣“先定一個能達(dá)到的小目標(biāo)痊土,比方說學(xué)會多態(tài)”肄扎。
【正文】今天帶大家深入理解面向?qū)ο蟮娜筇卣髦欢鄳B(tài)。
多態(tài):同一事物的多種形態(tài)赁酝。
首先咱們舉幾個例子來說明多態(tài)的概念犯祠。話說威哥兒子leo比較喜歡小動物,所以家里養(yǎng)了小貓酌呆,小狗和烏龜衡载。咱們學(xué)了繼承關(guān)系,所以如果有分析的話需要四個類:
共同的父類:Pet(寵物)
abstract class Pet{
abstract void run();
}
針對小狗我們會有一個狗類隙袁,來繼承寵物類痰娱,并重寫run的方法:
class Dog extends Pet{
void run() {
}
}
此時我們根據(jù)之前面向?qū)ο笾R,如果說創(chuàng)建一個狗類的話寫法是:
Dog d = new Dog();
也就是聲明一個狗類型的變量菩收,并通過構(gòu)造方法完成初始化梨睁,現(xiàn)在我們可以說有一只小狗叫做d;現(xiàn)在看著迎面跑來的這個小狗娜饵,威哥笑著對leo說:“l(fā)eo坡贺,你的小寵物跑來了”。注意這里的重點,你的小寵物跑過來了遍坟,你的小寵物拳亿,對,你沒看錯愿伴,是小寵物肺魁,那么咱們這個現(xiàn)實生活中的邏輯在代碼里同樣是通的,具體表現(xiàn)為:
Pet d = new Dog();
也就是說隔节,我們有一只狗鹅经,我們也可以叫做小寵物,專業(yè)叫法叫做:
父類引用指向子類對象
那有人說這個怎么跟多態(tài)能扯上關(guān)系官帘,簡單點理解就是一個對象,多種形態(tài)昧谊,左邊是一種寵物形態(tài)刽虹,右邊是一個狗形態(tài),這不就是多態(tài)么呢诬。
理解了多態(tài)的概念涌哲,那么咱們看看在程序中多態(tài)具體體現(xiàn)在那些方面:
1、對象的多態(tài)性:
我們看看對象的多態(tài)性如何引申出來尚镰。
現(xiàn)在我們要調(diào)用的話就是阀圾,在測試類中直接定義run方法,傳入Dog類型的參數(shù)狗唉,然后在主方法中創(chuàng)建Dog對象初烘,直接調(diào)用run方法,傳入dog分俯,具體代碼如下:
public static void main(String[] args) {
Dog dog = new Dog();
run(dog);
}
public static void run(Dog dog){
dog.run();
}
現(xiàn)在我又多了一個豬類:
豬類:
class Pig extends Pet{
void run() {
}
}
此時豬受寵了肾筐,leo又想看豬蠢萌的跑法了,那么此時又得定義
public static void main(String[] args) {
Dog dog = new Dog();
run(dog);
Pig pig = new Pig();
run(pig);
}
public static void run(Dog dog){
dog.run();
}
public static void run(Pig pig){
pig.run();
}
然后在main方法中創(chuàng)建Pig對象缸剪,然后調(diào)用run方法將pig對象傳入進(jìn)去吗铐。
哎,此時咱們帥氣的leo小男神看了龜兔賽跑杏节,又想看烏龜跑了唬渗,那么此時得創(chuàng)建一個烏龜類:
烏龜類:
class Tutle extends Pet{
void run() {
}
}
同樣的,需要調(diào)用的話奋渔,又得寫一個方法镊逝,傳入烏龜?shù)膮?shù)類型,具體如下:
public static void main(String[] args) {
Dog dog = new Dog();
run(dog);
Pig pig = new Pig();
run(pig);
Tutle tutle = new Tutle();
run(tutle);
}
public static void run(Dog dog){
dog.run();
}
public static void run(Pig pig){
pig.run();
}
public static void run(Tutle tutle){
tutle.run();
}
此時我們發(fā)現(xiàn)run方法是大量的重復(fù)嫉鲸,而且處理都是直接調(diào)用run方法蹋半,那么咱們之前也說了父類引用能指向子類對象,那么咱們就可以直接來個升級版:
public static void run(Pet pet){
pet.run();
}
此時,不管你傳入狗還是豬還是烏龜减江,都可以直接調(diào)用抽取出來的run方法染突,因為我們說了無論是狗,烏龜辈灼,還是豬都屬于寵物類型份企,都可以直接
public static void main(String[] args) {
Dog dog = new Dog();
run(dog);
Pig pig = new Pig();
run(pig);
Tutle tutle = new Tutle();
run(tutle);
}
此時結(jié)構(gòu)就很明朗了,那么此時我們顯而易見的是我們可以總結(jié)出擴展的好處了:
a) 提升了代碼的復(fù)用性巡莹;
并且司志,我們還有一點就是,如果后邊leo又準(zhǔn)備買一只兔子降宅,那么我們可以直接使用run方法骂远,創(chuàng)建兔子對象傳入即可,所以腰根,此處還有第二個好處:
b) 提高了代碼的擴展性激才,前面定義的結(jié)構(gòu)利于后邊使用。
當(dāng)然额嘿,針對接口也是一樣的瘸恼,上面的父類指父類結(jié)構(gòu),包括父類和父類接口册养。
2东帅、方法的多態(tài)性
方法的多態(tài)性包括方法的重載,方法的重寫等球拦。同樣也是一個事物多種形態(tài)的體現(xiàn)靠闭。
此處我們簡單跟大家總結(jié)一下重載和重寫的概念:
重載:同一類中,方法名相同坎炼,參數(shù)列表不同阎毅,返回值類型不能作為重載的判斷條件
重寫:子父類中,方法名相同点弯,參數(shù)列表相同扇调,返回值相同,子類重寫的權(quán)限要不小于父類方法的權(quán)限抢肛,子類中拋出的異常不能大于父類中拋出的異常狼钮。