polymorphism java_Java基础-面向对象第三大特性之多态(polymorphism)
Java基礎(chǔ)-面向?qū)ο蟮谌筇匦灾鄳B(tài)(polymorphism)
作者:尹正杰
版權(quán)聲明:原創(chuàng)作品,謝絕轉(zhuǎn)載!否則將追究法律責(zé)任。
一.多態(tài)概述
多態(tài)是繼封裝,繼承之后,面向?qū)ο蟮牡谌筇匦?#xff0c;多態(tài)的前提是繼承。
從現(xiàn)實(shí)事物經(jīng)常會(huì)體現(xiàn)出多種形態(tài),如學(xué)生,學(xué)生是人的一種,則一個(gè)具體的同學(xué)張三即是學(xué)生也是人。即出現(xiàn)兩種形態(tài)。Java作為面向?qū)ο蟮恼Z(yǔ)言,同樣可以描述一個(gè)事物的多種形態(tài)。如Student類(lèi)繼承了Person類(lèi),一個(gè)Student的對(duì)象便既是Student,又是Person。
最終多態(tài)體現(xiàn)為父類(lèi)引用變量可以指向子類(lèi)對(duì)象。多態(tài)的前提是必須有子父類(lèi)關(guān)系或者類(lèi)實(shí)現(xiàn)接口關(guān)系,否則無(wú)法完成多態(tài)。在使用多態(tài)后的父類(lèi)引用變量調(diào)用方法時(shí),會(huì)調(diào)用子類(lèi)重寫(xiě)后的方法。
二.多態(tài)調(diào)用的三種形式
多態(tài)調(diào)用方法,方法必須運(yùn)行子類(lèi)的重寫(xiě)!
1>.多態(tài)的定義格式:就是父類(lèi)的引用變量指向子類(lèi)對(duì)象。
1 父類(lèi)類(lèi)型 變量名 = new子類(lèi)類(lèi)型();2 變量名.方法名();
2>.普通類(lèi)多態(tài)定義的格式
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 classFather{8 public voidshow(){9 System.out.println("父類(lèi)的show方法!");10 }11 }12
13 class Son extendsFather{14 public voidshow(){15 System.out.println("子類(lèi)重寫(xiě)父類(lèi)的show方法!");16 }17 }18
19 public classMyInterfaceDemo{20 public static voidmain(String[] args){21 //Java中,對(duì)象的多態(tài)性,調(diào)用公式:“父類(lèi)類(lèi)型或者接口類(lèi)型 變量 = new 子類(lèi)對(duì)象();”
22 Father f = newSon();23 f.show();24 }25 }26
27
28
29 /*
30 以上代碼執(zhí)行結(jié)果如下:31 子類(lèi)重寫(xiě)父類(lèi)的show方法!32 */
3>.抽象類(lèi)多態(tài)定義的格式
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 abstract classFather{8 public abstract voideat();9 }10
11 class Son extendsFather{12 public voideat(){13 System.out.println("兒子喜歡吃米飯!");14 }15 }16
17 public classMyInterfaceDemo{18 public static voidmain(String[] args){19 //抽象類(lèi)Father,子類(lèi)是Son
20 Father f = newSon();21 f.eat();22 }23 }24
25
26
27 /*
28 以上代碼執(zhí)行結(jié)果如下:29 兒子喜歡吃米飯!30 */
4>.接口多態(tài)定義格式
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 interfaceFather{8 public abstract voidsmoking();9 }10
11 class Son implementsFather{12 public voidsmoking(){13 System.out.println("兒子會(huì)抽煙!");14 }15 }16
17 public classMyInterfaceDemo{18 public static voidmain(String[] args){19 //接口Father,實(shí)現(xiàn)類(lèi)Son
20 Father f = newSon();21 f.smoking();22 }23 }24
25
26
27 /*
28 以上代碼執(zhí)行結(jié)果如下:29 兒子會(huì)抽煙!30 */
三.多態(tài)中成員變量的特點(diǎn)
1>.成員變量(編譯運(yùn)行全看父類(lèi))
a>.編譯的時(shí)候,參考父類(lèi)中有沒(méi)有這個(gè)變量,如果有,編譯成功,沒(méi)有則編譯失敗;
b>.運(yùn)行的時(shí)候,運(yùn)行的是父類(lèi)中的變量值;
2>.成員方法(編譯看父類(lèi),運(yùn)行看子類(lèi)。)
a>.編譯的時(shí)候,參考父類(lèi)中有沒(méi)有這個(gè)方法,如果有,編譯成功,沒(méi)有則編譯失敗
b>.運(yùn)行的時(shí)候,運(yùn)行的是子類(lèi)的重寫(xiě)方法;
3>.靜態(tài)成員方法
沒(méi)有多態(tài)性。
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 classFather{8 int age = 30;9 public voidshow(){10 System.out.println("Father的方法");11 }12 }13
14 class Son extendsFather{15 int age = 8;16 public voidshow(){17 System.out.println("Son的方法");18 }19 }20
21 public classMyInterfaceDemo{22 public static voidmain(String[] args){23 Father f = newSon();24 System.out.println(f.age);25 f.show();26 }27 }28
29
30
31 /*
32 以上代碼執(zhí)行結(jié)果如下:33 3034 Son的方法35 */
四.instanceof關(guān)鍵字
我們了解多態(tài)之后,會(huì)發(fā)現(xiàn)一個(gè)對(duì)象的數(shù)據(jù)類(lèi)型不一定會(huì)保持不變。當(dāng)我們想要確定一個(gè)對(duì)象是否是某個(gè)類(lèi)時(shí),就會(huì)用到比較運(yùn)算符,只不過(guò)它很特殊,不能贏(yíng)大于小于或是等于號(hào)直接進(jìn)行判斷,而是要用到關(guān)鍵字,即instanceof,它只能用作比較引用數(shù)據(jù)類(lèi)型,用來(lái)比較一個(gè)引用類(lèi)型的變量,是不是這個(gè)類(lèi)型的對(duì)象。
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 abstract classPerson{8 public abstract voidsleep();9 }10
11
12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("學(xué)生在休息!");15 }16 }17
18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老師在休息!");21 }22 }23
24 public classPersonDemo{25 public static voidmain(String[] args){26
27 Person p = newStudent();28
29 p = newTeacher();30
31 boolean flag = p instanceofStudent;32
33 System.out.println("引用數(shù)據(jù)類(lèi)型'p'是否為Student類(lèi)型:>>> " +flag);34
35 p.sleep();36 }37 }38
39
40
41
42 /*
43 以上代碼執(zhí)行結(jié)果如下:44 引用數(shù)據(jù)類(lèi)型'p'是否為Student類(lèi)型:>>> false45 老師在休息!46 */
五.多態(tài)轉(zhuǎn)型
1>.多態(tài)的向上轉(zhuǎn)型
多態(tài)常見(jiàn)的就是自動(dòng)類(lèi)型提升,將取值范圍小的,自動(dòng)提升為取值范圍大的。范圍小的,看成是子類(lèi),范圍大的看成父類(lèi)。
優(yōu)點(diǎn):
這樣做的好出就是可以調(diào)用子類(lèi)父類(lèi)的公共屬性(方法)。
缺點(diǎn):
無(wú)法調(diào)用子類(lèi)特有的屬性(方法)。
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 abstract classPerson{8 public abstract voidsleep();9 }10
11
12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("學(xué)生在休息!");15 }16 }17
18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老師在休息!");21 }22 }23
24 public classPersonDemo{25 public static voidmain(String[] args){26
27 //從子類(lèi)對(duì)象往父類(lèi)變量賦值(自動(dòng)類(lèi)型提升,向上轉(zhuǎn)型)
28 Person p = newStudent();29
30 }31 }
2>.多態(tài)的向下轉(zhuǎn)型
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 abstract classPerson{8 public abstract voidsleep();9 }10
11
12 class Student extendsPerson{13 public voidsleep(){14 System.out.println("學(xué)生在休息!");15 }16 }17
18 class Teacher extendsPerson{19 public voidsleep(){20 System.out.println("老師在休息!");21 }22 }23
24 public classPersonDemo{25 public static voidmain(String[] args){26
27 //從子類(lèi)對(duì)象往父類(lèi)變量賦值(自動(dòng)類(lèi)型提升,向上轉(zhuǎn)型)
28 Person p = newStudent();29
30
31 //從父類(lèi)類(lèi)型轉(zhuǎn)向子類(lèi)類(lèi)型(向下轉(zhuǎn)型)
32 Student s =(Student)p;33
34 }35 }
3>.多態(tài)轉(zhuǎn)型的案例
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 abstract classAnimal{8 public abstract voideat();9 }10
11 class Cat extendsAnimal{12 public voideat(){13 System.out.println("貓吃貓糧!");14 }15
16 public voidcatchMouse(){17 System.out.println("貓抓老鼠!");18 }19 }20
21 class Dog extendsAnimal{22 public voideat(){23 System.out.println("狗吃狗糧!");24 }25
26 public voidrun(){27 System.out.println("狗能跑!");28 }29 }30
31 public classAnimalDemo{32 public static voidmain(String[] args){33 //兩個(gè)子類(lèi),使用兩次多態(tài)調(diào)用
34 Animal a1 = newCat();35 Animal a2 = newDog();36 //a1,a2調(diào)用子類(lèi)父類(lèi)共有方法,運(yùn)行走子類(lèi)的重寫(xiě)方法
37 a1.eat();38 a2.eat();39 /*類(lèi)型向下轉(zhuǎn)型,強(qiáng)制轉(zhuǎn)換,調(diào)用子類(lèi)的特有,防止發(fā)生異常,40 a1屬于CatUI小,轉(zhuǎn)成Cat類(lèi),a2屬于Dog對(duì)象,轉(zhuǎn)成Dog類(lèi),我們41 可以用關(guān)鍵字instanceof判斷。42 */
43 if(a1 instanceofCat){44 Cat c =(Cat)a1;45 c.catchMouse();46 }47
48 if(a2 instanceofDog){49 Dog d =(Dog)a2;50 d.run();51 }52
53 }54 }55
56
57 /*
58 以上代碼執(zhí)行結(jié)果如下:59 貓吃貓糧!60 狗吃狗糧!61 貓抓老鼠!62 狗能跑!63 */
六.匿名對(duì)象
1>.匿名對(duì)象的概念
匿名對(duì)象是指創(chuàng)建對(duì)象時(shí),只有創(chuàng)建對(duì)象的語(yǔ)句,卻沒(méi)有把對(duì)象地址值賦值給某個(gè)變量。
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 classPerson{8 public voideat(){9 System.out.println("人是鐵,飯是鋼,一頓不吃餓得慌!");10 }11 }12
13
14 public classPersonDemo{15 public static voidmain(String[] args){16
17 //有名字的對(duì)象,引用類(lèi)型變量,可以反復(fù)使用eat方法。
18 Person p = newPerson();19 p.eat();20
21 //匿名對(duì)象,沒(méi)有引用變量,只能使用一次,如果你再通過(guò)new調(diào)用eat方法的話(huà)實(shí)際上是又新生成了一個(gè)對(duì)象。
22 newPerson().eat();23 newPerson().eat();24
25 }26 }
2>.匿名對(duì)象的特點(diǎn)
a>.創(chuàng)建匿名對(duì)象直接使用,沒(méi)有變量名;
b>.匿名對(duì)象在沒(méi)有指定其引用變量時(shí),只能使用一次;
c>.匿名對(duì)象可以作為方法接受的參數(shù),方法返回值使用;
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 classPerson{8 public voideat(){9 System.out.println("人是鐵,飯是鋼,一頓不吃餓得慌!");10 }11 }12 public classPersonDemo{13 public static voidmain(String[] args){14 //有名字的對(duì)象,引用類(lèi)型變量,可以反復(fù)使用eat方法。
15 Person p = newPerson();16 p.eat();17 //匿名對(duì)象,沒(méi)有引用變量,只能使用一次,如果你再通過(guò)new調(diào)用eat方法的話(huà)實(shí)際上是又新生成了一個(gè)對(duì)象。
18 newPerson().eat();19 newPerson().eat();20 method(p);21
22 //匿名方法當(dāng)實(shí)參
23 method(newPerson());24 p =method();25 method(p);26 }27 //方法的返回值是Person類(lèi)型,方法的return語(yǔ)句,返回的是這個(gè)類(lèi)的對(duì)象。就可以用匿名對(duì)象來(lái)實(shí)現(xiàn)。
28 public staticPerson method(){29 return newPerson();30 }31 //調(diào)用方法method,傳遞Person類(lèi)型對(duì)象
32 public static voidmethod(Person p){33 p.eat();34 }35 }36
37
38
39 /*
40 以上代碼執(zhí)行結(jié)果如下:41 人是鐵,飯是鋼,一頓不吃餓得慌!42 人是鐵,飯是鋼,一頓不吃餓得慌!43 人是鐵,飯是鋼,一頓不吃餓得慌!44 人是鐵,飯是鋼,一頓不吃餓得慌!45 人是鐵,飯是鋼,一頓不吃餓得慌!46 人是鐵,飯是鋼,一頓不吃餓得慌!47 */
七.內(nèi)部類(lèi)
1>.內(nèi)部類(lèi)概念
a>.什么是內(nèi)部類(lèi)
將類(lèi)寫(xiě)在其它類(lèi)的內(nèi)部,可以寫(xiě)在其它類(lèi)的成員位置和局部位置,這時(shí)寫(xiě)在其它類(lèi)內(nèi)部的類(lèi)成為內(nèi)部類(lèi),其它類(lèi)也稱(chēng)為外部類(lèi)。
b>.什么時(shí)候使用內(nèi)部類(lèi)
在描述事物時(shí),若一個(gè)事物內(nèi)部還包含其它可能包含的事物,比如在描述汽車(chē)時(shí),汽車(chē)中還包含這發(fā)動(dòng)機(jī),這時(shí)發(fā)動(dòng)機(jī)就可以使用內(nèi)部類(lèi)來(lái)描述。
c>.內(nèi)部類(lèi)分類(lèi)
內(nèi)部類(lèi)分為成員內(nèi)部類(lèi)和局部?jī)?nèi)部類(lèi)。我們定義內(nèi)部類(lèi)時(shí),就是一個(gè)正常定義類(lèi)的過(guò)程,同樣包含各種修飾符,繼承與實(shí)現(xiàn)關(guān)系等。在內(nèi)部類(lèi)中可以直接訪(fǎng)問(wèn)外部類(lèi)的所有成員。
2>.成員內(nèi)部類(lèi)的調(diào)用格式
內(nèi)部類(lèi)可以使用外部類(lèi)成員,包括私有變量。外部類(lèi)要使用內(nèi)部類(lèi)的成員,必須建立內(nèi)部類(lèi)對(duì)象。
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 classOuter{8 private int a = 100;9 classInner{10 public voidinner(){11 System.out.println("內(nèi)部類(lèi)方法inter " +a);12 }13 }14 }15
16 public classInnerClassDemo{17 public static voidmain(String[] args){18 //創(chuàng)建內(nèi)部類(lèi)對(duì)象in
19 Outer.Inner in = new Outer().newInner();20 //調(diào)用內(nèi)部類(lèi)方法
21 in.inner();22 }23 }24
25
26 /*
27 以上代碼執(zhí)行結(jié)果如下:28 內(nèi)部類(lèi)方法inter 10029 */
3>.成員內(nèi)部類(lèi)的同名變量調(diào)用
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 classOuter{8 int a = 100;9 classInner{10 int a = 200;11 public voidinner(){12 int a = 300;13 System.out.println("內(nèi)部類(lèi)局部變量(內(nèi)部類(lèi)成員方法)訪(fǎng)問(wèn):>>> "+a);14 System.out.println("內(nèi)部類(lèi)成員變量訪(fǎng)問(wèn):>>> "+ this.a);15 System.out.println("外部類(lèi)成員變量訪(fǎng)問(wèn):>>> "+ Outer.this.a);16 }17 }18 }19
20 public classInnerClassDemo{21 public static voidmain(String[] args){22 //創(chuàng)建內(nèi)部類(lèi)對(duì)象in
23 Outer.Inner in = new Outer().newInner();24 //調(diào)用內(nèi)部類(lèi)方法
25 in.inner();26 }27 }28
29
30 /*
31 以上代碼執(zhí)行結(jié)果如下:32 內(nèi)部類(lèi)局部變量(內(nèi)部類(lèi)成員方法)訪(fǎng)問(wèn):>>> 30033 內(nèi)部類(lèi)成員變量訪(fǎng)問(wèn):>>> 20034 外部類(lèi)成員變量訪(fǎng)問(wèn):>>> 10035 */
3>.局部?jī)?nèi)部類(lèi)
局部?jī)?nèi)部類(lèi),定義在外部類(lèi)方法中的局部位置。與訪(fǎng)問(wèn)方法中的局部變量相似,可通過(guò)調(diào)用方法進(jìn)行訪(fǎng)問(wèn)。
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 classOuter{8 public voidout(){9 classInner{10 public voidinner(){11 System.out.println("局部?jī)?nèi)部類(lèi)方法!");12 }13 }14 //創(chuàng)建我們定義的Inner對(duì)象
15 Inner in = newInner();16 //調(diào)用創(chuàng)建好的對(duì)象的方法,這樣不管誰(shuí)只要能調(diào)用out方法就會(huì)觸發(fā)調(diào)用Inner類(lèi)中的inner()方法啦!
17 in.inner();18 }19 }20
21 public classInnerClassDemo{22 public static voidmain(String[] args){23 newOuter().out();24 }25 }26
27
28 /*
29 以上代碼執(zhí)行結(jié)果如下:30 局部?jī)?nèi)部類(lèi)方法!31 */
4>.匿名內(nèi)部類(lèi)
a>.匿名內(nèi)部類(lèi)概念
內(nèi)部類(lèi)是為了應(yīng)對(duì)更為復(fù)雜的類(lèi)間關(guān)系。查看源代碼中會(huì)涉及到,而在日常業(yè)務(wù)中很難遇到,這里不做贅述。最長(zhǎng)用到的內(nèi)部類(lèi)就是匿名內(nèi)部類(lèi),它是局部?jī)?nèi)部類(lèi)的一種。定義的匿名內(nèi)部類(lèi)有兩個(gè)含義:第一,臨時(shí)定義某一指定類(lèi)型的子類(lèi);第二,定義后即刻創(chuàng)建剛剛定義的這個(gè)子類(lèi)的對(duì)象。
b>.定義匿名內(nèi)部類(lèi)的作用與格式
匿名內(nèi)部類(lèi)是創(chuàng)建某個(gè)子類(lèi)對(duì)象的快捷方式。
1 /*
2 @author :yinzhengjie3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/
4 EMAIL:y1053419035@qq.com5 */
6
7 interfaceSmoking{8 public abstract voidsmoking();9 }10
11 public classSmokingDemo{12 public static voidmain(String[] args){13 //這就是用匿名對(duì)象實(shí)現(xiàn)接口并調(diào)用接口中的方法,切記不要忘記調(diào)用smoking()了喲!
14 newSmoking(){15 public voidsmoking(){16 System.out.println("運(yùn)維不喜歡吸煙!");17 }18 }.smoking();19 }20 }21
22 /*
23 以上代碼執(zhí)行結(jié)果如下:24 運(yùn)維不喜歡吸煙!25 */
總結(jié)
以上是生活随笔為你收集整理的polymorphism java_Java基础-面向对象第三大特性之多态(polymorphism)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: html加入购物车的动画,vue实现加入
 - 下一篇: java在W n8安装_在windows