Как исправить этот код, чтобы он работал правильно

1

Как я могу исправить этот код, чтобы он работал правильно?

Он должен напечатать bau bau и miao.

Код:

class Animal {
   // Nothing to define, this is only an example
}

class Dog extends Animal {  
   void say() {
      print("bau bau");
   }
}

class Cat extends Animal {
   void say() {
      print("miao");
   }
}

void setup() {
   Dog dog = new Dog();
   Cat cat = new Cat();

   ArrayList<Animal> list = new ArrayList<Animal>();
   list.add(dog);
   list.add(cat);

   for (Animal obj:list) {
      if (obj.say != null) obj.say(); //error here: say() is undefined
   }
}

Исключение:

say cannot be resolved or is not a field

Спасибо вам за помощь

Теги:
class
processing

5 ответов

3
Лучший ответ

Поскольку the say() method should be optional (см. Комментарии к вопросу OP), кажется, что вам нужен дополнительный интерфейс, например:

interface Sayable {
    void say();
}

Затем:

class Dog extends Animal implements Sayable {
    @Override
    public void say() {
        System.out.println("bau bau");
    }
}

class Cat extends Animal implements Sayable {
    @Override
    public void say() {
        System.out.println("miao");
    }
}

class Rabbit extends Animal {
    // a rabbit unfortunately does not speak,
    // so don't make it implement Sayable
}

А также:

Dog dog = new Dog();
Cat cat = new Cat();
Rabbit rabbit = new Rabbit();

ArrayList<Animal> list = new ArrayList<Animal>();
list.add(dog);
list.add(cat);
list.add(rabbit);

for (Animal obj : list) {
    if (obj instanceof Sayable) {
        Sayable sayable = (Sayable) obj;
        sayable.say();
    }
}

Печать:

bau bau
miao
  • 0
    Огромное спасибо ;)
3

Для хорошего порядка всегда используйте @Override. Это улавливает опечатки в имени метода или типах параметров.

class Animal {
   //nothing to defines, this is only an example
   void say() {
   }
}

class Dog extends Animal {  
   @Override
   void say() {
      print("bau bau");
   }
}

class Cat extends Animal {
   @Override
   void say() {
      print("miao");
   }
}

Теперь say() можно называть любым Animal, фактически ничего не делая (ваше упоминание о том, say оно необязательно, - Черепаха ничего не говорит и, следовательно, не имеет собственного чрезмерного say).

  • 1
    +3 и как он отвечает на вопрос оп
  • 0
    благодарю вас!! оно работает
Показать ещё 1 комментарий
3

Тип вашего ArrayList - это животное, поэтому нет гарантии, что метод say() существует в любом подклассе животного.

Вы можете добавить эту гарантию, создав абстрактный метод:

abstract class Animal {
   abstract void say();
}

Это гарантирует, что все подклассы Animal будут иметь метод say() (если они этого не делают, они не будут компилироваться.) Обратите внимание: теперь Animal является абстрактным, что делает его необратимым напрямую (поскольку любой класс с абстрактными методами также имеет быть абстрактным.)

Если это не то, что вы хотите, альтернативой может быть предоставление поведения по умолчанию в методе say у животных:

class Animal {
   @Override
   void say() {
        System.out.println("A bit confused");
   }
}

При таком поведении подклассы не вынуждены внедрять такой метод - если они этого не делают, тогда они получают поведение по умолчанию (как указано выше), если они это делают, то они переопределяют поведение по умолчанию с их реализацией и используют вместо этого. При желании (но я рекомендую это сделать), вы можете использовать аннотацию @Override чтобы указать, что вы должны переопределить метод, как указано выше. Таким образом, если вы по какой-то причине не превзошли его, он не будет компилироваться, что позволит вам обнаружить ошибку раньше.

1

Тип Animal не имеет открытого (или любого другого доступного доступа) поля, называемого say

obj.say
  • 0
    Animal не определяет, say поэтому, когда вы пытаетесь сослаться на объект Animal (который может быть Dog ), он не знает, say существует.
1

Чтобы он не был опциональным:

package com.rei.online;

import java.util.ArrayList;

class Animal {
}

interface Talking {
    void say();
}

class Dog extends Animal implements Talking {
    @Override
    public void say() {
        System.out.println("bau bau");
    }
}

class Cat extends Animal implements Talking {
    @Override
    public void say() {
        System.out.println("miao");
    }
}

class Whatever {
    public static void main(String... args) {
       Dog dog = new Dog();
       Cat cat = new Cat();

       ArrayList<Animal> list = new ArrayList<Animal>();
       list.add(dog);
       list.add(cat);

       for (Animal obj:list) {
          if (obj instanceof Talking) {
              Talking talker = (Talking) obj;
              talker.say();
          }
       }
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню