【Java基礎教程】java中的型別轉換與多型?

 Java是面嚮物件語言。這門語言其實相當年輕,於1995年才出現,由Sun公司出品。James Gosling領導了Java的專案小組。該專案的最初只想為家電設計一門容易移植的語言。如果你想要跟著一群有經驗的人一起學習JAVA,或者是你想要能夠每天晚上有人能夠帶著你一起做企業級的專案可以加裙,422-912、489

方法/步驟

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

型別檢查

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

型別不符,賣萌無效↓↓

【Java基礎教程】java中的型別轉換與多型

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

【Java基礎教程】java中的型別轉換與多型

【Java基礎教程】java中的型別轉換與多型

【Java基礎教程】java中的型別轉換與多型

javac將返回:

【Java基礎教程】java中的型別轉換與多型

基本型別轉換

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

【Java基礎教程】java中的型別轉換與多型

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

【Java基礎教程】java中的型別轉換與多型

upcast與多型

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

【Java基礎教程】java中的型別轉換與多型

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

【Java基礎教程】java中的型別轉換與多型

【Java基礎教程】java中的型別轉換與多型

程式執行結果:

shit, broken cup

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

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

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

比如下面的繼承關係:

【Java基礎教程】java中的型別轉換與多型

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

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

【Java基礎教程】java中的型別轉換與多型

程式執行結果:

shit, 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()。我們可以在自己的類定義中覆蓋這些方法。

【Java基礎教程】java中的型別轉換與多型

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

我將在以後深入Object類。

總結

基本型別轉換

polymorphism

downcast

Object

相關問題答案