2015-02-24 42 views
2

我有一個多態數組,我需要修復底部的兩行代碼。 我無法理解多態性,我試圖找出它的邏輯。Java中的多態性問題

在此代碼我假定動物=超類,狗=亞類中,貓=亞類:

Animal[] animals = new Animal[20]; 
animals[0] = new Dog(); 
animals[1] = new Cat(); 

//these two below don't work 
Dog lassie = animals[0]; 
Cat fluffy = animals[1]; 
+0

編譯器是不夠聰明,知道'動物[0]'總是擁有狗。 – immibis 2015-02-24 02:40:38

+0

這會做什麼? 'if(Math.random()<0.5)animals [0] = new Dog();其他動物[0] =新貓();狗d =動物[0];' – immibis 2015-02-24 02:41:04

回答

3

它不會工作,因爲該陣列的類型是Animal,這意味着在所述對象陣列的類型爲Animal。您正在將一個單獨的元素分配給該特定動物的引用,但該對象的類型爲Animal,即使實際元素是DogCat也可能是DogCat。編譯器不知道什麼樣的Animal它是沒有演員。

要使該聲明起作用,您需要將其轉換爲適當的類型。

Dog lassie = (Dog) animals[0]; 
Cat fluffy = (Cat) animals[1]; 

多態性不過,是不是真的以這種方式使用,因爲這個想法是,你作爲用戶,不需要知道具體類型的Animal,只是它是一個Animal

假設你Animal類中定義一個名爲speak()抽象方法,你的子類都實現了它,System.out.println("Woof")DogSystem.out.println("Meow")Cat,以保持它的簡單。

例子:

public abstract class Animal { 
    public abstract void speak(); 
} 

public class Dog extends Animal { 
    @Override 
    public void speak() { 
     System.out.println("Woof!"); 
    } 
} 

public class Cat extends Animal { 
    @Override 
    public void speak() { 
     System.out.println("Meow!"); 
    } 
} 

如果你再有你的數組作爲這樣的:

Animal[] animals = new Animal[20]; 
animals[0] = new Dog(); 
animals[1] = new Cat(); 

for (Animal a : animals) { 
    a.speak(); // you don't know what Animal it is, but the proper speak method will be called. 
} 
1

這不是如何使用多態。這個想法是,一旦你將元素添加到多態集合中,你應該將它們全部視爲Animal。如果它們具有不同的行爲,那麼它會進入在超類上定義並在子類中實現的多態方法。讓我知道如果這不明確。

1

您正在嘗試一種類型的Animal分配給Dog(從Animal假設Dog繼承),分配不能工作,因爲編譯器只能保證對象是一類Animal的,也可能是一個Horse所有它知道

但是你可以再次施放AnimalDogCat,假設DogAnimal

Dog lassie = (Dog)animals[0]; 
Cat fluffy = (Cat)animals[1]; 
繼承

話雖如此,我會非常小心盲目鑄造值這種方式。

當定義一個數組Animal,你基本上是說,我不關心的內容,只要它符合類/接口Animal的合同要求,除此之外,你不應該關心

0

對於animal[0]animal[1],靜態類型爲Animal。所以基本上你告訴java:

讓這個Dog lassie成爲一個動物。並讓這個Cat fluffy成爲一個動物。但並非所有的動物都是貓或狗。看看爲什麼Java可能會因此而不高興?

你需要使用一個種姓安撫的Java:

Dog lassie = (Dog) animals[0]; 
Cat fluffy = (Cat) animals[1];