亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

詳解Java多態對象的類型轉換與動態綁定

2019-11-26 14:58:06
字體:
來源:轉載
供稿:網友

Java多態對象的類型轉換
這里所說的對象類型轉換,是指存在繼承關系的對象,不是任意類型的對象。當對不存在繼承關系的對象進行強制類型轉換時,java 運行時將拋出 java.lang.ClassCastException 異常。

在繼承鏈中,我們將子類向父類轉換稱為“向上轉型”,將父類向子類轉換稱為“向下轉型”。

很多時候,我們會將變量定義為父類的類型,卻引用子類的對象,這個過程就是向上轉型。程序運行時通過動態綁定來實現對子類方法的調用,也就是多態性。

然而有些時候為了完成某些父類沒有的功能,我們需要將向上轉型后的子類對象再轉成子類,調用子類的方法,這就是向下轉型。

注意:不能直接將父類的對象強制轉換為子類類型,只能將向上轉型后的子類對象再次轉換為子類類型。也就是說,子類對象必須向上轉型后,才能再向下轉型。請看下面的代碼:

public class Demo {  public static void main(String args[]) {    SuperClass superObj = new SuperClass();    SonClass sonObj = new SonClass();    // 下面的代碼運行時會拋出異常,不能將父類對象直接轉換為子類類型    // SonClass sonObj2 = (SonClass)superObj;    // 先向上轉型,再向下轉型    superObj = sonObj;    SonClass sonObj1 = (SonClass)superObj;  }}class SuperClass{ }class SonClass extends SuperClass{ } 

將第7行的注釋去掉,運行時會拋出異常,但是編譯可以通過。

因為向下轉型存在風險,所以在接收到父類的一個引用時,請務必使用 instanceof 運算符來判斷該對象是否是你所要的子類,請看下面的代碼:

public class Demo {  public static void main(String args[]) {    SuperClass superObj = new SuperClass();    SonClass sonObj = new SonClass();    // superObj 不是 SonClass 類的實例    if(superObj instanceof SonClass){      SonClass sonObj1 = (SonClass)superObj;    }else{      System.out.println("①不能轉換");    }    superObj = sonObj;    // superObj 是 SonClass 類的實例    if(superObj instanceof SonClass){      SonClass sonObj2 = (SonClass)superObj;    }else{      System.out.println("②不能轉換");    }  }}class SuperClass{ }class SonClass extends SuperClass{ }

運行結果:

①不能轉換

總結:對象的類型轉換在程序運行時檢查,向上轉型會自動進行,向下轉型的對象必須是當前引用類型的子類。

Java多態和動態綁定
在Java中,父類的變量可以引用父類的實例,也可以引用子類的實例。

請讀者先看一段代碼:

public class Demo {  public static void main(String[] args){    Animal obj = new Animal();    obj.cry();    obj = new Cat();    obj.cry();    obj = new Dog();    obj.cry();  }}class Animal{  // 動物的叫聲  public void cry(){    System.out.println("不知道怎么叫");  }  }class Cat extends Animal{  // 貓的叫聲  public void cry(){    System.out.println("喵喵~");  }}class Dog extends Animal{  // 狗的叫聲  public void cry(){    System.out.println("汪汪~");  }}

運行結果:

不知道怎么叫喵喵~汪汪~

上面的代碼,定義了三個類,分別是 Animal、Cat 和 Dog,Cat 和 Dog 類都繼承自 Animal 類。obj 變量的類型為 Animal,它既可以指向 Animal 類的實例,也可以指向 Cat 和 Dog 類的實例,這是正確的。也就是說,父類的變量可以引用父類的實例,也可以引用子類的實例。注意反過來是錯誤的,因為所有的貓都是動物,但不是所有的動物都是貓。

可以看出,obj 既可以是人類,也可以是貓、狗,它有不同的表現形式,這就被稱為多態。多態是指一個事物有不同的表現形式或形態。

再比如“人類”,也有很多不同的表達或實現,TA 可以是司機、教師、醫生等,你憎恨自己的時候會說“下輩子重新做人”,那么你下輩子成為司機、教師、醫生都可以,我們就說“人類”具備了多態性。

多態存在的三個必要條件:要有繼承、要有重寫、父類變量引用子類對象。

當使用多態方式調用方法時:
首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,則檢查子類是否覆蓋了該方法。
如果子類覆蓋了該方法,就調用子類的方法,否則調用父類方法。

從上面的例子可以看出,多態的一個好處是:當子類比較多時,也不需要定義多個變量,可以只定義一個父類類型的變量來引用不同子類的實例。請再看下面的一個例子:

public class Demo {  public static void main(String[] args){    // 借助多態,主人可以給很多動物喂食    Master ma = new Master();    ma.feed(new Animal(), new Food());    ma.feed(new Cat(), new Fish());    ma.feed(new Dog(), new Bone());  }}// Animal類及其子類class Animal{  public void eat(Food f){    System.out.println("我是一個小動物,正在吃" + f.getFood());  }}class Cat extends Animal{  public void eat(Food f){    System.out.println("我是一只小貓咪,正在吃" + f.getFood());  }}class Dog extends Animal{  public void eat(Food f){    System.out.println("我是一只狗狗,正在吃" + f.getFood());  }}// Food及其子類class Food{  public String getFood(){    return "事物";  }}class Fish extends Food{  public String getFood(){    return "魚";  }}class Bone extends Food{  public String getFood(){    return "骨頭";  }}// Master類class Master{  public void feed(Animal an, Food f){    an.eat(f);  }}

運行結果:

我是一個小動物,正在吃事物我是一只小貓咪,正在吃魚我是一只狗狗,正在吃骨頭

Master 類的 feed 方法有兩個參數,分別是 Animal 類型和 Food 類型,因為是父類,所以可以將子類的實例傳遞給它,這樣 Master 類就不需要多個方法來給不同的動物喂食。
動態綁定

為了理解多態的本質,下面講一下Java調用方法的詳細流程。

1) 編譯器查看對象的聲明類型和方法名。

假設調用 obj.func(param),obj 為 Cat 類的對象。需要注意的是,有可能存在多個名字為func但參數簽名不一樣的方法。例如,可能存在方法 func(int) 和 func(String)。編譯器將會一一列舉所有 Cat 類中名為func的方法和其父類 Animal 中訪問屬性為 public 且名為func的方法。

這樣,編譯器就獲得了所有可能被調用的候選方法列表。

2) 接下來,編澤器將檢查調用方法時提供的參數簽名。

如果在所有名為func的方法中存在一個與提供的參數簽名完全匹配的方法,那么就選擇這個方法。這個過程被稱為重載解析(overloading resolution)。例如,如果調用 func("hello"),編譯器會選擇 func(String),而不是 func(int)。由于自動類型轉換的存在,例如 int 可以轉換為 double,如果沒有找到與調用方法參數簽名相同的方法,就進行類型轉換后再繼續查找,如果最終沒有匹配的類型或者有多個方法與之匹配,那么編譯錯誤。

這樣,編譯器就獲得了需要調用的方法名字和參數簽名。

3) 如果方法的修飾符是private、static、final(static和final將在后續講解),或者是構造方法,那么編譯器將可以準確地知道應該調用哪個方法,我們將這種調用方式 稱為靜態綁定(static binding)。

與此對應的是,調用的方法依賴于對象的實際類型, 并在運行時實現動態綁。例如調用 func("hello"),編澤器將采用動態綁定的方式生成一條調用 func(String) 的指令。

4)當程序運行,并且亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

日韩精品在线影院| 中文字幕亚洲精品| 国产精品一区二区三区在线播放| 久久久久久久91| 黄色成人av网| 日韩av最新在线| 欧美久久精品午夜青青大伊人| 欧美成人免费全部观看天天性色| 国产日韩欧美综合| 69av视频在线播放| 亚洲国产小视频| 亚洲国产日韩欧美在线99| 日韩免费看的电影电视剧大全| 欧美日韩国产一区中文午夜| 亚洲一区美女视频在线观看免费| 欧美乱大交做爰xxxⅹ性3| 久久久噜噜噜久久中文字免| 亚洲精选中文字幕| 欧美激情精品久久久久| 亚洲成人动漫在线播放| 亚洲性夜色噜噜噜7777| 国产精品亚洲片夜色在线| 欧美人与性动交| 日韩中文字幕第一页| 伊人伊成久久人综合网小说| 日本一区二三区好的精华液| 欧美激情videoshd| 992tv成人免费视频| 欧美精品久久久久a| 97色伦亚洲国产| 日韩高清中文字幕| 久久久国产一区| 欧美国产激情18| 热re91久久精品国99热蜜臀| 亚洲最新av在线网站| 91中文字幕在线| 久久久久久久亚洲精品| 欧美成人免费在线观看| 日韩成人中文字幕在线观看| 亚洲一区亚洲二区亚洲三区| 青草成人免费视频| 日韩中文在线中文网在线观看| 久久91亚洲精品中文字幕奶水| 国产在线拍偷自揄拍精品| 伊人久久精品视频| 亚洲高清一区二| 综合国产在线观看| 亚洲自拍高清视频网站| 国产精品日日摸夜夜添夜夜av| 俺去亚洲欧洲欧美日韩| 全亚洲最色的网站在线观看| 国产精品入口福利| 国产精品久久一| 国产成人福利视频| 26uuu另类亚洲欧美日本老年| 中文字幕在线看视频国产欧美| 亚洲激情视频在线播放| 亚洲色图校园春色| 久久夜色精品国产| 影音先锋欧美在线资源| 国内精品小视频| 国产精品精品久久久| 久久精品亚洲94久久精品| 国产精品美女主播| 欧美性xxxxx极品娇小| 精品呦交小u女在线| 日韩视频免费在线| 久久中文字幕视频| 91夜夜揉人人捏人人添红杏| 国产欧美韩国高清| 精品国产拍在线观看| 亚洲激情视频网| 国产美女精品免费电影| 亚洲午夜精品久久久久久性色| 亚洲欧美日韩视频一区| 久久久国产精品亚洲一区| 久久中文字幕一区| 国产精品一区二区3区| 国产裸体写真av一区二区| 91亚洲va在线va天堂va国| 日日噜噜噜夜夜爽亚洲精品| 欧美电影第一页| 欧美有码在线观看| 日本高清不卡的在线| 日产日韩在线亚洲欧美| 精品日本高清在线播放| 亚洲人成啪啪网站| 色中色综合影院手机版在线观看| 日韩中文字幕在线免费观看| 色av吧综合网| 2019亚洲男人天堂| 播播国产欧美激情| 日韩国产高清视频在线| 97在线免费观看视频| 亚洲欧美中文日韩在线| 一区二区三欧美| 久久中国妇女中文字幕| 成人精品视频在线| 日韩一区二区三区xxxx| 亚洲国产女人aaa毛片在线| 欧美激情二区三区| 国产精品高潮粉嫩av| 成人免费大片黄在线播放| 日本精品视频网站| 亚洲最大福利视频网| 亚洲剧情一区二区| 日韩成人高清在线| 成人国产精品久久久久久亚洲| 国内自拍欧美激情| 欧美日韩一区二区在线| 国产脚交av在线一区二区| 欧美国产精品va在线观看| 日韩精品中文在线观看| 国产成人亚洲综合青青| 欧美高清第一页| 久久国产加勒比精品无码| 麻豆国产精品va在线观看不卡| 亚洲天堂av在线播放| 国产福利视频一区二区| 欧美一级高清免费播放| 亚洲精品国产欧美| 亚洲美女中文字幕| 欧美成人精品三级在线观看| 亚洲日本成人网| 中文字幕亚洲无线码a| 国产一区二区三区三区在线观看| 亚洲精品一区二区三区不| 91九色精品视频| 久久久久久久久久久网站| 亚洲精品一区在线观看香蕉| 亚洲国产精品久久久久| 欧洲精品久久久| 精品视频在线播放免| 欧美一级黄色网| 欧美日韩精品在线观看| 国产一区二区三区精品久久久| 亚洲国产精品人久久电影| 日韩中文字幕免费视频| 九九视频直播综合网| 国产精品成人免费电影| 亚洲精品国产成人| 国产精品高潮视频| 激情久久av一区av二区av三区| 国产丝袜一区视频在线观看| 亚洲国产97在线精品一区| 超碰日本道色综合久久综合| 九九久久国产精品| 2019中文字幕在线免费观看| 国产91精品久久久久久| 国内精品久久久久久久久| 日韩av手机在线| 久久亚洲精品小早川怜子66| 国产精品视频一区二区高潮| 日韩视频永久免费观看| 中文字幕亚洲欧美日韩在线不卡| 这里只有精品视频在线| 超在线视频97| 最好看的2019的中文字幕视频| 91精品国产自产在线观看永久| 91免费精品国偷自产在线| 国产精品免费一区二区三区都可以| 亚洲精品99久久久久中文字幕| 亚洲成人久久一区| 欧美成人精品三级在线观看|