CodeGym /Java Course /All lectures for TW purposes /多態性,第 3 部分

多態性,第 3 部分

All lectures for TW purposes
等級 1 , 課堂 564
開放

1. 類型轉換

存儲引用類型(類)的變量也可以轉換為不同的類型。但這僅適用於單一類型層次結構。讓我們看一個簡單的例子。假設我們有以下類層次結構,其中下面的類繼承上面的類。

類型轉換

引用類型和原始類型的類型轉換也被歸類為擴大和縮小。

我們看到 Cat 類繼承了 Pet 類,而 Pet 類又繼承了 Animal 類。

如果我們這樣寫代碼:

Animal kitten = new Cat();

這是一個擴大的類型轉換。它也稱為隱式轉換。我們擴大了cat引用,現在它指向一個Cat對象。通過這樣的類型轉換,我們將無法使用kitten引用來調用Cat類中存在但Animal類中不存在的方法。

縮小轉換(或顯式轉換)發生在相反的方向:

Cat cat = (Cat) kitten;

我們明確指出我們想要將存儲在kitten變量(其類型為Animal )中的引用轉換為Cat類型。



2.檢查對象的類型

但是你在這裡需要非常小心。如果你這樣做:

Animal beast = new Cat();
Wolf grayWolf = (Wolf) beast;

編譯器會允許這段代碼,但是程序運行的時候會出現錯誤!JVM 會拋出一個異常:

Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to a Wolf

對Cat對象的引用只能存儲在類型為 Cat 類的祖先的變量中:Pet、Animal 或 Object。

這是為什麼?

這裡的相關點是對象引用用於引用該對象的方法和變量。如果我們使用 Animal 變量來存儲對 Cat 對象的引用,就不會有任何問題:Cat 類型始終具有 Animal 類型的變量和方法——它繼承了它們!

但是如果 JVM 允許我們在 Wolf 變量中存儲對 Cat 對象的引用,那麼我們可能會遇到這樣一種情況:我們可能會嘗試使用 grayWolf 變量來調用存儲在該變量中的 Cat 對像中不存在方法. 這就是為什麼這種安排是不允許的。

Java 有一個特殊的instanceof運算符,可以讓您檢查對像是否屬於某種類型,因此是否可以存儲到某種類型的變量中。它看起來很簡單:

variable instanceof Type

例子:

Animal beast = new Cat();
if (beast instanceof Wolf)
{
   Wolf grayWolf = (Wolf) beast;
}

此代碼不會導致錯誤 — 即使在運行時也是如此。

這裡有一些例子可以說明這種情況:

加寬類型轉換 描述
Cow cow = new Whale();

這是一個經典的擴大轉換——不需要類型轉換運算符。Cow現在只能在對像上調用類中定義的方法Whale

cow變量上,編譯器只會讓你調用它的類型(類Cow)具有的方法。

縮小類型轉換
Cow cow = new Whale();
if (cow instanceof Whale)
{
   Whale whale = (Whale) cow;
}
經典收縮轉換:您需要添加類型檢查和強制轉換運算符。
變量Cow cow存儲對對象的引用Whale
我們驗證是這樣的,然後進行(縮小)類型轉換。或者它也被稱為:
類型轉換
.

Cow cow = new Cow();
Whale whale = (Whale) cow; // Exception
您可以在不檢查對像類型的情況下縮小引用類型。
如果cow變量引用的對像不是 a ,則將生成 Whalean 。InvalidClassCastException


3.調用原始方法:super關鍵字

當覆蓋父類的方法時,有時我們不想用我們自己的方法替換它,而只是想稍微補充一下。

如果能在我們的方法中調用父類的方法,然後執行一些我們自己的代碼就好了。或者也許先執行我們自己的代碼,然後再調用父類的方法。

而 Java 讓我們做到了這一點。要調用父類的方法,請執行以下操作:

super.method(arguments);

例子:

class PeaceTime
{
   public double getPi()
   {
      return 3.14;
   }
}

class WarTime extends PeaceTime
{
   public double getPi()
   {
      return super.getPi()*2;  // 3.14*2
   }
}

戰時,值Pi可以大於6!當然,我們是在開玩笑,但這個例子演示了這一切是如何工作的。

這裡有幾個例子來澄清一些事情:

代碼 描述
class Cow
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a cow");
   }
}

class Whale extends Cow
{
   public void printName()
   {
      System.out.print("This is incorrect: ");
      super.printName();
      System.out.println("I'm a whale");
   }
}
CowWhale
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printAll();
}
屏幕輸出將是:
I'm a white whale
This is incorrect: I'm a cow
I'm a whale

這是很難的事情。老實說,這是OOP中最難的事情之一。也就是說,您確實需要知道並理解它。


留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION