2017-08-12 4 views
1

Je suis bloqué par un problème. Mon problème va comme ceci. J'ai une super-classe Animal et deux sous-classes Human And Bird. J'ai une méthode fly dans ma super classe Animal qui fournira une implémentation à la fois pour la classe Human et Bird basée sur l'interface Flyable.Java Interface Design Pattern Situation

Ma classe d'animaux ressemble à ceci.

public class`Animal{ 

    public Flyable flyable; 

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

} 

classe humaine ressemble à ce

class Human extends Animal { 

    Flyable flyable; 

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

} 

classe des oiseaux ressemble à ce

class Bird extends Animal { 

     Flyable flyable; 

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

    } 

Interfaces sont ci-dessous

public interface Flyable { 
    public void fly(); 
} 

public class CantFly implements Flyable{ 

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

Quand j'appelle

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

Il me donne NullPointerException

Ce que je suis manque ici?.
Je supposais. Depuis que j'appelle new Human() il initialise l'interface Flyable dans la super-classe Animal. Ai-je tort?

J'ai résolu ce problème en changeant la conception de la méthode.
voler (flyable flyable) .So je ne veux pas cette solution de conception. Je me souviens face à ce problème quand j'exécutait un algorithme de recherche pour une application qui fournira une liste de résultat, mais un élément de liste aura différentes UI
,
https appel à différentes URL de fin,
Parsing JSON,
Mapping à différentes classes de POJO.
Malheureusement, j'ai dû résoudre ce problème avec une autre approche que j'ai mentionnée.

+0

Pourquoi avez-vous le champ 'flyable' dans le parent ___and___ les sous-classes? Quel sens devrait avoir la duplication? – Tom

+0

En superclasse pour appeler la méthode de l'interface Flyable. Et dans la sous-classe pour initialiser le flyable. Considérez-vous cela comme une mauvaise approche? –

+0

Oui, c'est faux. Si vous avez besoin du champ dans la classe parent, passez l'initialisation à cette classe (par exemple 'super (new CantFly());'). – Tom

Répondre

7

Human hérite de Animal, donc tous ses champs sont implicitement "copiés" à partir de Animal. Par conséquent, vous n'avez pas besoin de redéclarer flyable à nouveau dans Human et Bird.

Mais vous l'avez fait. Cela provoque les nouveaux champs flyable dans les sous-classes à masquer le champ d'origine déclaré dans Animal. Par conséquent, lorsque vous faites:

flyable = new CantFly(); 

à Human, vous attribuez une valeur à la flyable dans Human, pas le flyable dans Animal.

Alors vous avez fait ceci:

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

fly dans Animal utilise le champ flyable qui est déclarée dans Animal classe, qui n'a pas encore été attribué (vous ne le flyable attribué à Human)! Un NPE se produit en conséquence.

Pour résoudre ce problème, supprimez simplement tous les champs flyable dans les sous-classes Animal. De cette façon, il n'y a que un champflyable.

Remarque

Je pense que cette conception un peu étrange. Human ne peut pas voler, donc il ne devrait pas vraiment avoir un champ flyable. En fait, rien ne devrait avoir un champ flyable. Parmi ces 3 classes, seul Bird devrait implémenter Flyable.

+0

lemme essayez-le en code mann. Je reviendrai à toi. –

+0

Même la Superclasse ne devrait pas avoir d'interface Flyable, suggérez-vous? –

+0

@RohitSingh 'Animal' ne devrait pas implémenter' Flyable' car tous les animaux ne peuvent pas voler. – Sweeper