国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java基礎教程之類型轉(zhuǎn)換與多態(tài)

2019-11-26 15:26:24
字體:
供稿:網(wǎng)友

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

 類型檢查

Java的任意變量和引用經(jīng)過類型聲明(type declaration),才能使用。我們之前見過對象數(shù)據(jù)、類數(shù)據(jù)、方法參數(shù)、方法返回值以及方法內(nèi)部的自動變量,它們都需要聲明其類型。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  : Cuprequired: Human        aPerson = new Cup();                    ^1 error

 基本類型轉(zhuǎn)換

Java可以對基本類型的變量進行類型轉(zhuǎn)換。不同的基本類型有不同的長度和存儲范圍。如果我們從一個高精度類型轉(zhuǎn)換到低精度類型,比如從float轉(zhuǎn)換到int,那么我們有可能會損失信息。這樣的轉(zhuǎn)換叫做收縮變換(narrowing conversion)。這種情況下,我們需要顯示的聲明類型轉(zhuǎn)換,比如:

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

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

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

 

基本類型轉(zhuǎn)換

 upcast與多態(tài)

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

我們可以將一個衍生類引用轉(zhuǎn)換為其基類引用,這叫做向上轉(zhuǎn)換(upcast)或者寬松轉(zhuǎn)換。下面的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");  }}

程序運行結(jié)果:

shit, broken cup

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

我們隨后調(diào)用了aCup(我們聲明它為Cup類型)的addWater()方法。盡管aCup是Cup類型的引用,它實際上調(diào)用的是BrokenCup的addWater()方法!也就是說,即使我們經(jīng)過upcast,將引用的類型寬松為其基類,Java依然能正確的識別對象本身的類型,并調(diào)用正確的方法。Java可以根據(jù)當前狀況,識別對象的真實類型,這叫做多態(tài)(polymorphism)。多態(tài)是面向?qū)ο蟮囊粋€重要方面。

多態(tài)是Java的支持的一種機制,同時也是面向?qū)ο蟮囊粋€重要概念。這提出了一個分類學的問題,既子類對象實際上“是”父類對象。比如一只鳥,也是一個動物;一輛汽車,也必然是一個交通工具。Java告訴我們,一個衍生類對象可以當做一個基類對象使用,而Java會正確的處理這種情況。

比如下面的繼承關系:

 

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

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

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);  }}

程序運行結(jié)果:

shit, no water inside

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

 downcast

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

 Object類型

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

Object: 祖先

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

我將在以后深入Object類。

 (多態(tài)的實現(xiàn)是依靠RTTI的支持。我將在以后深入。)

 總結(jié)

基本類型轉(zhuǎn)換

polymorphism

downcast

Object

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 古田县| 社旗县| 江北区| 旬阳县| 益阳市| 博湖县| 二连浩特市| 兰考县| 庄浪县| 兰考县| 达日县| 镇江市| 平利县| 图们市| 建湖县| 桑日县| 集安市| 滁州市| 巴中市| 博客| 新民市| 屏南县| 公安县| 澄城县| 庄浪县| 阳谷县| 白玉县| 周宁县| 呼图壁县| 新津县| 旬阳县| 上栗县| 泽普县| 莱阳市| 大关县| 宁陕县| 贺州市| 内乡县| 喀喇沁旗| 龙游县| 绵阳市|