Задание: Написать программу которая будет иметь классы и они будут наследоваться. Animal -> Felling -> Tiger, Lion, Cat.
Вопрос: В своём коде я создавал каждый конечный элемент иерархии наследования (Tiger, Lion, Cat) по одному экземпляру и добавлял их в ArrayList
ArrayList<Animals> animals = new ArrayList<>();
animals.add(new Cat());
animals.add(new Tiger());
animals.add(new Lion());
Вот методы классов
abstract public class Animals {
abstract public void voice();
abstract public void walk();
abstract public void eat();
abstract public class Felline extends Animals {
abstract public void voice();
public void walk(){
System.out.println("Walking like a Felline");
}
public void eat(){
System.out.println("Eating like a Felline");
}
public void sitDown(){
System.out.println("Sitting down like a Felline");
}
}
public class Cat extends Felline{
@Override
public void voice(){
System.out.println("Mew!");
}
}
(В классах Tiger, Lion тоже самое что и в Cat)
Я могу получить доступ к методам класса Animal таким образом
animals.get(i).voice();
Но каким образом теперь мне можно получить метод sitDown()?
Буду очень признателен за ответ. 3 день не могу найти решение.
В данном примере используется 2 уровня абстракции, классы: Animals (первый (высший) уровень) и его наследник Felline (второй уровень). В классе Felline добавлен новый метод public void sitDown();
, который "не виден" в супер-классе Animals. Он об этом методе даже "не догадывается"))) Далее - при создании коллекции ArrayList ты указал, что в ней будут храниться объекты типа Animals
ArrayList<Animals> animals = new ArrayList<>();
т.е. классы, наследуемые от высшей ступени твоей иерархии абстракции (Animals - Felline - Cat,Dog,Lion), что вполне допустимо. При использовании метода voice();
любого элемента коллекции проблем нет. Этот метод "известен" на всех уровнях абстракции. А вот с методом sitDown();
немного сложнее. Ты указал, что тип элементов коллекции будет Animals, но на этом (высшем) уровне этот метод не виден(см.выше).
Таким образом, чтобы использовать данный метод необходимо либо явно, прямо в коде приводить к типу Felline:
((Felline)animals.get(i)).sitDown()
о чём тебе пояснил Serodv, либо поменять тип элементов при объявлении коллекции, понизить его до уровня Felline:
import java.util.ArrayList;
public class AnimalTestDrive{
public static void main(String[] args){
ArrayList<Felline> animals = new ArrayList<>();
animals.add(new Cat());
animals.get(0).voice();
animals.get(0).sitDown();
}
}
Кстати, на заметку, английское слово Feline (кошачий) пишется с одной буквой "l", но это я так, для расширения кругозора )))
Ваш ArrayList
может хранить либо объекты типа Animals
, либо экземпляры его подклассов. Но в классе Animals
отсутствует метод sitDown()
, а значит, не все Animals
могут обладать данным методом (а только лишь Feline
, где вы его определили).
Следовательно, есть 2 выхода из данной ситуации:
Исходя из вашего кода, ваш ArrayList
хранит лишь только экземпляры подклассов класса Feline
(Cat
, Lion
, Tiger
), а значит, изменив тип Animals
на Feline
, вы буквально скажите, что мой ArrayList
будет состоять только из Feline
и экземпляров его подклассов. Но, как было сказано выше, ваш метод sitDown()
находится в абстрактном классе Feline
, а значит, все его подклассы тоже имеют данный метод. Таким образом, можно просто вызвать данный метод:
List<Feline> felines = new ArrayList<>();
felines.sitDown();
ArrayList
могут быть и другие Animals
(не Feline
), то у них этот метод отсутствует, следовательно, нужно делать проверку instanceof
, а также приведение типов, что накладывает дополнительные расходы и ухудшает читаемость кода.Arrays
и т.д.);Программируйте к интерфейсу, а не к конкретной реализации (принцип подстановки Барбары Лисков):
List<Animals> animals = new ArrayList<>()
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
пишу небольшую программу, столкнулся с такой проблеммой не могу скомпилировать, т к ява не может найти главный класс,погуглил проблему но ничего...
Хотите улучшить этот вопрос? Добавьте больше подробностей и уточните проблему, отредактировав это сообщение
Я хочу сделать игру платформер (используя Processing) и столкнулся с такой проблемойУ меня есть 2 типа блоков: стационарные (неподвижные) и те которые...
Появилась ошибка в Eclipse Window Builder Я в eclipse новичок, не знаю как исправить!