Java基礎12 類型轉換與多態

來源:互聯網
上載者:User

標籤:

 

我們之前使用類創造新的類型(type),並使用繼承來便利我們建立類的過程。我將在這一講中深入類型,並介紹多態(polymorphism)的概念。

 

類型檢查

Java的任意變數和引用經過型別宣告(type declaration),才能使用。我們之前見過對象資料、類資料、方法參數、方法傳回值以及方法內部的自動變數,它們都需要聲明其類型。Java是一種強型別(strongly typing)語言,它會對類型進行檢查。如果我們錯誤的使用類型,將造成錯誤。

 類型不符,賣萌無效

 

比如在下面的Test類中,我們將一個Cup類對象賦予給aPerson類引用:

 
public class Test{    public static void main(String[] args)    {        Human aPerson;            
aPerson = new Cup(); }}class Human{ /** * constructor */ public Human(int h) { this.height = h; } /** * accessor */ public int getHeight() { return this.height; } /** * mutator */ public void growHeight(int h) { this.height = this.height + h; } private int height;}class Cup { public void addWater(int w) { this.water = this.water + w; } public void drinkWater(int w) { this.water = this.water - w; } private int water = 0;}
 

javac將返回:

found   : Cup
required: Human
                aPerson = new Cup();             
                          ^
1 error

 

基本類型轉換

Java可以對基本類型的變數進行類型轉換。不同的基本類型有不同的長度和儲存範圍。如果我們從一個高精度類型轉換到低精度類型,比如從float轉換到int,那麼我們有可能會損失資訊。這樣的轉換叫做收縮變換(narrowing conversion)。這種情況下,我們需要顯示的宣告類型轉換,比如:

 
public class Test{    public static void main(String[] args)    {        int a;        a = (int) 1.23;  // narrowing conversion        System.out.println(a);    }}
 

 

如果我們從低精度類型轉換成高精度類型,則不存在資訊損失的顧慮。這樣的變換叫做寬鬆變換(widening conversion)。我們不需要顯示的要求類型轉換,Java可以自動進行:

 
public class Test{    public static void main(String[] args)    {         int a = 3;        double b;        b = a;  // widening conversion        System.out.println(a);    }}
 

 

基本類型轉換

 

upcast與多態

在Java中,引用也可以進行類型轉換,但是有限制。

我們可以將一個衍生類引用轉換為其基類引用,這叫做向上轉換(upcast)或者寬鬆轉換。下面的BrokenCup類繼承自Cup類,並覆蓋了Cup類中原有的addWater()和drinkWater()方法:

 
 
public class Test{    public static void main(String[] args)    {         Cup aCup;
BrokenCup aBrokenCup = new BrokenCup();
aCup = aBrokenCup; // upcast aCup.addWater(10); // method binding }
}

class Cup { public void addWater(int w) { this.water = this.water + w; } public void drinkWater(int w) { this.water = this.water - w; } private int water = 0;}class BrokenCup extends Cup{ public void addWater(int w) { System.out.println("shit, broken cup"); } public void drinkWater(int w) { System.out.println("om...num..., no water inside"); }}
 

程式運行結果:

shit, broken cup

 

在上面可以看到,不需要任何顯示說明,我們將衍生類引用aBrokenCup賦予給它的基類引用aCup。類型轉換將由Java自動進行。

我們隨後調用了aCup(我們聲明它為Cup類型)的addWater()方法。儘管aCup是Cup類型的引用,它實際上調用的是BrokenCup的addWater()方法!也就是說,即使我們經過upcast,將引用的類型寬鬆為其基類,Java依然能正確的識別對象本身的類型,並調用正確的方法。Java可以根據當前狀況,識別對象的真實類型,這叫做多態(polymorphism)。多態是物件導向的一個重要方面。

 

多態是Java的支援的一種機制,同時也是物件導向的一個重要概念。這提出了一個分類學的問題,既子類對象實際上“是”父類對象。比如一隻鳥,也是一個動物;一輛汽車,也必然是一個交通工具。Java告訴我們,一個衍生類對象可以當做一個基類對象使用,而Java會正確的處理這種情況。

比如下面的繼承關係:

 

 

我們可以說用杯子(Cup)喝水(drinkWater)。實際上,喝水這個動作具體含義會在衍生類中發生很大變換。比如用吸管喝水,和從一個破杯子喝水,這兩個動作差別會很大,雖然我們抽象中都講“喝水”。我們當然可以針對每個衍生類分別編程,調用不同的drinkWater方法。然而,作為程式員,我們可以對杯子編程,調用Cup的drinkWater()方法,而無論這個杯子是什麼樣的衍生類杯子。Java會調用相應的正確方法,正如我們在上面程式中看到的。

看一個更加有意義的例子,我們給Human類增加一個drink()方法,這個方法接收一個杯子物件和一個整數作為參數。整數表示喝水的水量:

 
public class Test{    public static void main(String[] args)    {        Human guest = new Human();        BrokenCup hisCup  = new BrokenCup();        guest.drink(hisCup, 10);    }}class Human {    void drink(Cup aCup, int w)    {        aCup.drinkWater(w);    }}
 

程式運行結果:

om...num..., no water inside

 

我們在Human類的drink()的定義中,要求第一個參量為Cup類型的引用。但在實際運用時(Test類),將Cup的BrokenCup衍生類對象。這實際上是將hisCup向上轉型稱為Cup類,傳遞給drink()方法。在方法中,我們調用了drinkWater()方法。Java發現這個對象實際上是BrokenCup對象,所以實際調用了BrokenCup的相應方法。

 

downcast

我們可以將一個基類引用向下轉型(downcast)成為衍生類的引用,但要求該基類引用所指向的對象,已經是所要downcast的衍生類對象。比如可以將上面的hisCup向上轉型為Cup類引用後,再向下轉型成為BrokenCup類引用。

 

Object類型

Java中,所有的類實際上都有一個共同的繼承祖先,即Object類。Object類提供了一些方法,比如toString()。我們可以在自己的類定義中覆蓋這些方法。

Object: 祖先

 

我們可以編寫一個操作Object對象的程式,就可以通過upcast,將任意對象傳遞給該程式。

我將在以後深入Object類。

 

(多態的實現是依靠RTTI的支援。我將在以後深入。)

 

總結

基本類型轉換

polymorphism

downcast

Object

Java基礎12 類型轉換與多態

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.