2017-08-12 56 views
1

我被困在一個問題。 我的問題是這樣的。 我有一個超類Animal和兩個子類Human和Bird。 我在我的超級動物中有一個飛行方法,它將爲基於可飛行接口的人類和鳥類提供實現。Java界面設計模式情況

我的動物類看起來像這樣。

public class`Animal{ 

    public Flyable flyable; 

    public void fly() 
    { 
     flyable.fly(); 
    } 

} 

人力類看起來像這樣

class Human extends Animal { 

    Flyable flyable; 

    public Human() 
    { 
    flyable = new CantFly(); 
    } 

} 

鳥類看起來像這樣

class Bird extends Animal { 

     Flyable flyable; 

     public Bird() 
     { 
     flyable = new FlyHigh(); 
     } 

    } 

接口都在下面

public interface Flyable { 
    public void fly(); 
} 

public class CantFly implements Flyable{ 

    @Override 
    public void fly() 
    { 
    Sysout("cant fly"); 
    } 

當我打電話

Animal me = new Human(); 
me.fly(); 

它給我的NullPointerException

什麼我米在這裏失蹤?
我假設。由於我正在調用新的Human(),它會在超類Animal中初始化Flyable接口。我錯了嗎?

我已經通過改變方法的設計解決了這個問題。
fly(Flyable flyable)。所以我不想那個設計解決方案。 我記得當面向我實現了一個應用程序的https打電話給其他結束的URL的搜索算法,將提供結果,但列表項的列表將有不同的
UI,

解析JSON這個問題,
映射到不同的POJO類。
很遺憾,我不得不用我提到的替代方法來解決這個問題。

+0

爲什麼你在父母___和子類中有'flyable'字段?重複應該是什麼意思? – Tom

+0

在超類中調用Flyable接口的方法。並在子類中初始化flyable。你認爲這是錯誤的做法嗎? –

+0

是的,那是錯的。如果您需要父類中的字段,則將初始化傳遞給該類(例如'super(new CantFly());')。 – Tom

回答

7

Human繼承自Animal,所以它的所有字段都從Animal隱式「複製」。因此,您不需要在HumanBird中重新聲明flyable

但你做到了。這導致子類中新的flyable字段的隱藏原始字段在Animal中聲明。因此,當你做:

flyable = new CantFly(); 
Human

,您在Human分配一個值flyable,而不是在Animalflyable

然後你這樣做:

Animal me = new Human(); 
me.fly(); 

flyAnimal使用在Animal類,尚未分配的聲明的字段flyable(你只分配flyableHuman)!結果發生NPE。

要解決此問題,只需刪除Animal的子類中的所有flyable字段。這種方式只有一個flyable字段。

我覺得這個設計有點怪。 Human不能飛,所以它不應該有一個flyable字段。實際上,沒有任何字段應該有flyable。在這三類中,只有Bird應該執行Flyable

+0

lemme試一試代碼曼。我會回到你身邊。 –

+0

即使超類不應該有Flyable接口你建議? –

+0

@RohitSingh動物不應該實施「可飛翔」,因爲不是所有的動物都可以飛行。 – Sweeper