Ситуация с шаблоном дизайна интерфейса Java

Я застрял в проблеме. Моя проблема выглядит так. У меня есть суперкласс Animal и два подкласса Human And Bird. У меня есть метод fly в моем суперклассе Animal, который предоставит реализацию для класса Human и Bird на основе Flyable Interface.

Мой класс животных выглядит следующим образом.

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

Что мне здесь не хватает?
Я предполагал. Поскольку я вызываю new Human(), он инициализирует интерфейс Flyable в суперклассе Animal. Я ошибся?

Я решил эту проблему, изменив дизайн метода.
летать (Flyable flyable). Так что я не хочу это дизайнерское решение. Я помню, как сталкивался с этой проблемой, когда реализовывал алгоритм поиска для приложения, которое будет предоставлять список результатов, но элемент списка будет отличаться
UI,
https вызов различных конечных URL,
Разбор JSON,
Отображение на разные классы POJO.
К сожалению, мне пришлось решить эту проблему с помощью альтернативного подхода, который я упомянул.

1 ответ

Решение

Human наследуется от Animalпоэтому все его поля неявно "копируются" из Animal, Поэтому вам не нужно переопределять flyable снова в Human а также Bird,

Но вы сделали. Это вызывает новый flyable поля в подклассах, чтобы скрыть исходное поле, объявленное в Animal, Как следствие, когда вы делаете:

flyable = new CantFly();

в Human, вы присваиваете значение flyable в Human, не flyable в Animal,

Тогда вы сделали это:

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

fly в Animal использует поле flyable что заявлено в Animal класс, который еще не был назначен flyable в Human)! NPE возникает в результате.

Чтобы это исправить, просто удалите все flyable поля в подклассах Animal, Таким образом, есть только один flyable поле.

Заметка

Я считаю этот дизайн немного странным. Human не может летать, поэтому он не должен иметь flyable поле. На самом деле, ничто не должно иметь flyable поле. Среди этих 3 классов только Bird следует реализовать Flyable,

Другие вопросы по тегам