Java——上溯造型&下溯造型__Java

來源:互聯網
上載者:User
public   abstract   class  Animal {     public   abstract   void  speak();     public   void  eat(){         // 吃吃吃。。。     }}


public   interface  DoorGod {     void  guard();}

public   class  Cat  extends  Animal {    @Override     public   void  eat() {         try  {            Thread.sleep( 1000 );        }  catch  (InterruptedException e) {            e.printStackTrace();        }         super .eat();    }    @Override     public   void  speak() {        System.out.println( " 喵喵 " );    }}

public   class  Dog  extends  Animal  implements  DoorGod{    @Override     public   void  speak() {        System.out.println( " 汪汪 " );    }     public   void  guard() {         while ( true ){            System.out.println( " 汪汪 " );        }    }    }
  其中Animal 為基類,定義speak 和eat 方法,eat 方法給出了空實現; DoorGod 為門神介面,定義了 guard 方法來守護家門; Cat 為繼承Animal 的子類,這裡假定貓有挑食的習慣,在eat 中要耽擱點時間看看夥食;Dog 也為繼承Animal 的子類,同時它實現了DoorGod 介面來守護家門。

 先說說上溯造型(upcasting)。這個術語緣於繼承關係圖的傳統畫法:將基類至於頂部,而向下發展的就是衍生類別。根據上面的sample,我給出下面的一個小應用:

public class Main {    public static void upcasting(Animal animal){        animal.speak();        animal.eat();    }    public static void main(String[] args) {        Animal dog1 = new Dog();        upcasting(dog1);                Dog dog2 = new Dog();        upcasting(dog2);    }}

由於upcasting(Animal animal)方法的參數是 Animal類型的,因此如果傳入的參數是 Animal的子類,傳入的參數就會被轉換成父類Animal類型,這樣你建立的Dog對象能使用的方法只是Animal中的簽名方法;也就是說,在上溯的過程中,Dog的介面變窄了,它本身的一些方法(例如實現了 DoorGod的guard方法)就不可見了。如果你想使用Dog中存在而Animal中不存在的方法(比如guard方法),編譯時間不能通過的。由此可見,上溯造型是安全的類型轉換。另一方面,雖然upcasting(Animal animal)方法的參數是 Animal類型,但傳入的參數可以是Animal的衍生類別(這也是OO編程中慣用的編程方法),這裡面就有個對象的類型識別問題,也就是運行時類型識別(run-time type identification,縮寫為RTTI) ,這也可以單獨寫一篇文章了,《Thinking in Java》中的第10章詳細地闡述了RTTI。

相對於類型轉換安全的上溯造型,下溯造型就未必是安全的了。我們經常會做些強制類型轉換的事情,有時我們也會無意間遇到 ClassCastException的轉換異常(從這一點來說,我們應該多用範型來避免不安全的類型轉換)。例如:

public static void downcasting(Animal animal){        //DoorGod doorGod = (DoorGod)animal;        if(animal instanceof DoorGod){            DoorGod doorGod = (DoorGod)animal;            doorGod.guard();        }        if(animal instanceof Cat){            Cat cat = (Cat)animal;            cat.speak();        }} 

如果沒有採取措施(上面使用的措施是 instanceof )判斷對象的類型,那麼向下的強制轉換就是不安全的。這種轉換錯誤在編譯時間是不能檢測出來的,只有在運行時才會拋出 ClassCastException 異常,對於測試來說,這樣的錯誤也是很難檢測的。

來源:http://www.blogjava.net/kafka0102/archive/2007/05/21/118998.html



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.