polymorphism java_Java基础-面向对象第三大特性之多态(polymorphism)
Java基礎-面向對象第三大特性之多態(polymorphism)
作者:尹正杰
版權聲明:原創作品,謝絕轉載!否則將追究法律責任。
一.多態概述
多態是繼封裝,繼承之后,面向對象的第三大特性,多態的前提是繼承。
從現實事物經常會體現出多種形態,如學生,學生是人的一種,則一個具體的同學張三即是學生也是人。即出現兩種形態。Java作為面向對象的語言,同樣可以描述一個事物的多種形態。如Student類繼承了Person類,一個Student的對象便既是Student,又是Person。
最終多態體現為父類引用變量可以指向子類對象。多態的前提是必須有子父類關系或者類實現接口關系,否則無法完成多態。在使用多態后的父類引用變量調用方法時,會調用子類重寫后的方法。
二.多態調用的三種形式
多態調用方法,方法必須運行子類的重寫!
1>.多態的定義格式:就是父類的引用變量指向子類對象。
1 父類類型 變量名 = new子類類型();2 變量名.方法名();
2>.普通類多態定義的格式
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("父類的show方法!");10 }11 }12
13 class Son extendsFather{14 public voidshow(){15 System.out.println("子類重寫父類的show方法!");16 }17 }18
19 public classMyInterfaceDemo{20 public static voidmain(String[] args){21 //Java中,對象的多態性,調用公式:“父類類型或者接口類型 變量 = new 子類對象();”
22 Father f = newSon();23 f.show();24 }25 }26
27
28
29 /*
30 以上代碼執行結果如下:31 子類重寫父類的show方法!32 */
3>.抽象類多態定義的格式
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 //抽象類Father,子類是Son
20 Father f = newSon();21 f.eat();22 }23 }24
25
26
27 /*
28 以上代碼執行結果如下:29 兒子喜歡吃米飯!30 */
4>.接口多態定義格式
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("兒子會抽煙!");14 }15 }16
17 public classMyInterfaceDemo{18 public static voidmain(String[] args){19 //接口Father,實現類Son
20 Father f = newSon();21 f.smoking();22 }23 }24
25
26
27 /*
28 以上代碼執行結果如下:29 兒子會抽煙!30 */
三.多態中成員變量的特點
1>.成員變量(編譯運行全看父類)
a>.編譯的時候,參考父類中有沒有這個變量,如果有,編譯成功,沒有則編譯失敗;
b>.運行的時候,運行的是父類中的變量值;
2>.成員方法(編譯看父類,運行看子類。)
a>.編譯的時候,參考父類中有沒有這個方法,如果有,編譯成功,沒有則編譯失敗
b>.運行的時候,運行的是子類的重寫方法;
3>.靜態成員方法
沒有多態性。
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 以上代碼執行結果如下:33 3034 Son的方法35 */
四.instanceof關鍵字
我們了解多態之后,會發現一個對象的數據類型不一定會保持不變。當我們想要確定一個對象是否是某個類時,就會用到比較運算符,只不過它很特殊,不能贏大于小于或是等于號直接進行判斷,而是要用到關鍵字,即instanceof,它只能用作比較引用數據類型,用來比較一個引用類型的變量,是不是這個類型的對象。
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("學生在休息!");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("引用數據類型'p'是否為Student類型:>>> " +flag);34
35 p.sleep();36 }37 }38
39
40
41
42 /*
43 以上代碼執行結果如下:44 引用數據類型'p'是否為Student類型:>>> false45 老師在休息!46 */
五.多態轉型
1>.多態的向上轉型
多態常見的就是自動類型提升,將取值范圍小的,自動提升為取值范圍大的。范圍小的,看成是子類,范圍大的看成父類。
優點:
這樣做的好出就是可以調用子類父類的公共屬性(方法)。
缺點:
無法調用子類特有的屬性(方法)。
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("學生在休息!");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 //從子類對象往父類變量賦值(自動類型提升,向上轉型)
28 Person p = newStudent();29
30 }31 }
2>.多態的向下轉型
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("學生在休息!");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 //從子類對象往父類變量賦值(自動類型提升,向上轉型)
28 Person p = newStudent();29
30
31 //從父類類型轉向子類類型(向下轉型)
32 Student s =(Student)p;33
34 }35 }
3>.多態轉型的案例
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 //兩個子類,使用兩次多態調用
34 Animal a1 = newCat();35 Animal a2 = newDog();36 //a1,a2調用子類父類共有方法,運行走子類的重寫方法
37 a1.eat();38 a2.eat();39 /*類型向下轉型,強制轉換,調用子類的特有,防止發生異常,40 a1屬于CatUI小,轉成Cat類,a2屬于Dog對象,轉成Dog類,我們41 可以用關鍵字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 以上代碼執行結果如下:59 貓吃貓糧!60 狗吃狗糧!61 貓抓老鼠!62 狗能跑!63 */
六.匿名對象
1>.匿名對象的概念
匿名對象是指創建對象時,只有創建對象的語句,卻沒有把對象地址值賦值給某個變量。
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 //有名字的對象,引用類型變量,可以反復使用eat方法。
18 Person p = newPerson();19 p.eat();20
21 //匿名對象,沒有引用變量,只能使用一次,如果你再通過new調用eat方法的話實際上是又新生成了一個對象。
22 newPerson().eat();23 newPerson().eat();24
25 }26 }
2>.匿名對象的特點
a>.創建匿名對象直接使用,沒有變量名;
b>.匿名對象在沒有指定其引用變量時,只能使用一次;
c>.匿名對象可以作為方法接受的參數,方法返回值使用;
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 //有名字的對象,引用類型變量,可以反復使用eat方法。
15 Person p = newPerson();16 p.eat();17 //匿名對象,沒有引用變量,只能使用一次,如果你再通過new調用eat方法的話實際上是又新生成了一個對象。
18 newPerson().eat();19 newPerson().eat();20 method(p);21
22 //匿名方法當實參
23 method(newPerson());24 p =method();25 method(p);26 }27 //方法的返回值是Person類型,方法的return語句,返回的是這個類的對象。就可以用匿名對象來實現。
28 public staticPerson method(){29 return newPerson();30 }31 //調用方法method,傳遞Person類型對象
32 public static voidmethod(Person p){33 p.eat();34 }35 }36
37
38
39 /*
40 以上代碼執行結果如下:41 人是鐵,飯是鋼,一頓不吃餓得慌!42 人是鐵,飯是鋼,一頓不吃餓得慌!43 人是鐵,飯是鋼,一頓不吃餓得慌!44 人是鐵,飯是鋼,一頓不吃餓得慌!45 人是鐵,飯是鋼,一頓不吃餓得慌!46 人是鐵,飯是鋼,一頓不吃餓得慌!47 */
七.內部類
1>.內部類概念
a>.什么是內部類
將類寫在其它類的內部,可以寫在其它類的成員位置和局部位置,這時寫在其它類內部的類成為內部類,其它類也稱為外部類。
b>.什么時候使用內部類
在描述事物時,若一個事物內部還包含其它可能包含的事物,比如在描述汽車時,汽車中還包含這發動機,這時發動機就可以使用內部類來描述。
c>.內部類分類
內部類分為成員內部類和局部內部類。我們定義內部類時,就是一個正常定義類的過程,同樣包含各種修飾符,繼承與實現關系等。在內部類中可以直接訪問外部類的所有成員。
2>.成員內部類的調用格式
內部類可以使用外部類成員,包括私有變量。外部類要使用內部類的成員,必須建立內部類對象。
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("內部類方法inter " +a);12 }13 }14 }15
16 public classInnerClassDemo{17 public static voidmain(String[] args){18 //創建內部類對象in
19 Outer.Inner in = new Outer().newInner();20 //調用內部類方法
21 in.inner();22 }23 }24
25
26 /*
27 以上代碼執行結果如下:28 內部類方法inter 10029 */
3>.成員內部類的同名變量調用
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("內部類局部變量(內部類成員方法)訪問:>>> "+a);14 System.out.println("內部類成員變量訪問:>>> "+ this.a);15 System.out.println("外部類成員變量訪問:>>> "+ Outer.this.a);16 }17 }18 }19
20 public classInnerClassDemo{21 public static voidmain(String[] args){22 //創建內部類對象in
23 Outer.Inner in = new Outer().newInner();24 //調用內部類方法
25 in.inner();26 }27 }28
29
30 /*
31 以上代碼執行結果如下:32 內部類局部變量(內部類成員方法)訪問:>>> 30033 內部類成員變量訪問:>>> 20034 外部類成員變量訪問:>>> 10035 */
3>.局部內部類
局部內部類,定義在外部類方法中的局部位置。與訪問方法中的局部變量相似,可通過調用方法進行訪問。
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("局部內部類方法!");12 }13 }14 //創建我們定義的Inner對象
15 Inner in = newInner();16 //調用創建好的對象的方法,這樣不管誰只要能調用out方法就會觸發調用Inner類中的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 以上代碼執行結果如下:30 局部內部類方法!31 */
4>.匿名內部類
a>.匿名內部類概念
內部類是為了應對更為復雜的類間關系。查看源代碼中會涉及到,而在日常業務中很難遇到,這里不做贅述。最長用到的內部類就是匿名內部類,它是局部內部類的一種。定義的匿名內部類有兩個含義:第一,臨時定義某一指定類型的子類;第二,定義后即刻創建剛剛定義的這個子類的對象。
b>.定義匿名內部類的作用與格式
匿名內部類是創建某個子類對象的快捷方式。
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 //這就是用匿名對象實現接口并調用接口中的方法,切記不要忘記調用smoking()了喲!
14 newSmoking(){15 public voidsmoking(){16 System.out.println("運維不喜歡吸煙!");17 }18 }.smoking();19 }20 }21
22 /*
23 以上代碼執行結果如下:24 運維不喜歡吸煙!25 */
總結
以上是生活随笔為你收集整理的polymorphism java_Java基础-面向对象第三大特性之多态(polymorphism)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html加入购物车的动画,vue实现加入
- 下一篇: java美元兑换,(Java实现) 美元