2017-08-12 7 views
1

Ich bin bei einem Problem fest. Mein Problem geht so. Ich habe eine Oberklasse Tier und zwei Unterklassen Mensch und Vogel. Ich habe eine Fly-Methode in meiner Superklasse Animal, die eine Implementierung für die Klasse Mensch und Vogel basierend auf der Flyable-Schnittstelle bereitstellen wird.Java Interface Design Pattern Situation

Meine Tierklasse sieht so aus.

public class`Animal{ 

    public Flyable flyable; 

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

} 

Mensch Klasse sieht wie folgt aus

class Human extends Animal { 

    Flyable flyable; 

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

} 

Vogel Klasse ähnliche Schnittstellen

class Bird extends Animal { 

     Flyable flyable; 

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

    } 

sieht sind unter

public interface Flyable { 
    public void fly(); 
} 

public class CantFly implements Flyable{ 

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

Als ich

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

nennen es gibt mir Nullpointer

Was ich hier vermisse?.
Ich nahm an. Da ich New Human() anrufe, initialisiert es die Flyable-Schnittstelle in der Superklasse Animal. Liege ich falsch?

Ich habe dieses Problem gelöst, indem ich das Design der Methode änderte.
fliegen (Flyable Flyable) .So will ich nicht, dass Design-Lösung. Ich erinnere mich, mit diesem Problem konfrontiert, als ich einen Suchalgorithmus für eine App Implementierung, die eine Liste der Ergebnis aber Listenelement unterschiedliche
UI, um verschiedene End-URLs,
Parsing JSON,
Mapping
https aufrufen müssen bieten wird zu verschiedenen POJO-Klassen.
Leider musste ich dieses Problem mit einem alternativen Ansatz lösen, den ich erwähnt habe.

+0

Warum haben Sie das 'flyable' Feld in den Eltern ___and___ der Unterklassen? Welchen Sinn sollte die Duplizierung haben? – Tom

+0

In der Oberklasse, um die Methode der Flyable-Schnittstelle zu nennen. Und in der Unterklasse, um das Flyable zu initialisieren. Siehst du das als falsche Herangehensweise? –

+0

Ja, das ist falsch. Wenn Sie das Feld in der Elternklasse benötigen, übergeben Sie die Initialisierung an diese Klasse (z. B. 'super (new CantFly());'). – Tom

Antwort

7

Human erbt von Animal, so werden alle seine Felder implizit von Animal "kopiert". Daher müssen Sie flyable in Human und Bird nicht erneut deklarieren.

Aber du hast. Dies führt dazu, dass die neuen Felder flyable in den Unterklassen das ursprünglich in Animal deklarierte Feld ausblenden. Als Folge, wenn Sie tun:

flyable = new CantFly(); 

in Human, zuweisen Sie einen Wert an die flyable in Human, nicht die flyable in Animal.

Dann haben Sie diese:

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

fly in Animal verwendet das Feld flyable, die in Animal Klasse deklariert wird, die noch nicht zugeordnet worden ist (nur die flyable in Human zugewiesen)! Ein NPE tritt als Ergebnis auf. Um dieses Problem zu beheben, entfernen Sie einfach alle flyable Felder in den Unterklassen Animal. Auf diese Weise gibt es nur einflyable Feld.

Hinweis

Ich denke, dieses Design ein wenig seltsam. Human kann nicht fliegen, so sollte es nicht wirklich ein flyable Feld haben. In der Tat sollte nichts ein flyable Feld haben. Unter diesen 3 Klassen sollte nur BirdFlyable implementieren.

+0

Lemme versuchen Sie es in Code Mann. Ich werde zu dir zurückkommen. –

+0

Auch Superklasse sollte nicht Flyable-Schnittstelle haben Sie vorschlagen? –

+0

@RohitSingh 'Animal' sollte' Flyable' nicht implementieren, da nicht alle Tiere fliegen können. – Sweeper