Я запутался в полиморфизме - PullRequest
1 голос
/ 05 февраля 2011

Я знаю правило полиморфизма, которое мы можем отправить через такой параметр, как этот код

interface Animal {
  void whoAmI();
}

class A implements Animal{

    @Override
    public void whoAmI() {
        // TODO Auto-generated method stub
        System.out.println("A");
    }

}

class B implements Animal{

    @Override
    public void whoAmI() {
        // TODO Auto-generated method stub
        System.out.println("B");
    }

}

class RuntimePolymorphismDemo {

public void WhoRU(List t){
    System.out.println(t.getClass());
}

public static void main(String[] args) {
     A a = new A();
     B b = new B();

     RuntimePolymorphismDemo rp = new RuntimePolymorphismDemo();
     rp.WhoRU(a);
     rp.WhoRU(b);
  }
}

но

 List<Example> examples = new ArrayList<Example>();

В приведенном выше коде яне понимаю, почему мы должны использовать List<Example>.

Почему мы не можем использовать подобное?

ArrayList<Example> examples = new ArrayList<Example>();

Потому что, когда мы используем List<Example>, мы не можем использовать метод, который существует только в ArrayList классе, таком как trimToSize()

Как я могу узнать, когда использовать или не использовать?

Ответы [ 4 ]

7 голосов
/ 05 февраля 2011

Причина использования List, а не ArrayList, заключается в том, что если вы хотите использовать функцию List и не заботиться о ее реализации, тогда простое использование базового интерфейса или абстрактного класса дает вам большую гибкость.

Если вам нужны специальные функции ArrayList, вы можете указать его, но если в будущем вы решите изменить реализацию на что-то отличное от ArrayList, это затруднит изменение (так как вам придется изменитьваш код везде, на который он ссылается, а не просто базовый код).

2 голосов
/ 05 февраля 2011

List - это интерфейс . ArrayList - это конкретный тип , реализация .

Если вам нужно использовать только функции из List, тогда вы объявите переменную List. Затем, если станет доступна новая полезная реализация List (скажем, MySuperFastList), вы можете поменять ее местами в коде, и вам потребуется только одно изменение.

1 голос
/ 05 февраля 2011

- это то же самое, что, расширяя ваш пример кода, мы говорим:

Animal a=new A();
Animal b=new B();

Вы можете без проблем назначить «более производный тип» для менее производного, фактически вы можете создать, всегда ссылаясь на ваш пример, массив Anymal, заполнить его некоторыми экземплярами A и B и увидеть полиморфизм в работе зацикливаясь на массиве и вызывая каждого «животного» WhoAmI ()

0 голосов
/ 05 февраля 2011

Этот код, я не понимаю, почему мы должны использовать List. почему мы не можем так использовать?

ArrayList<Example> examples = new ArrayList<Example>();

Прежде всего, пожалуйста, не думайте, что вы не можете этого сделать - это совершенно законно.

Поскольку это законно, то совершенно естественно задаться вопросом, почему вы часто видите такой код:

List<Example> examples = new ArrayList<Example>();

Потому что, когда мы используем List, мы не можем использовать метод, который есть только в классе ArrayList, например trimToSize ()

Опять же, вы очень хорошо разбираетесь в полиморфизме. Это действительно разветвление использования List здесь вместо ArrayList.

List<Example> examples = new ArrayList<Example>();

Использование интерфейса List здесь вместо конкретного класса ArrayList следует общепринятой передовой практике: по возможности использовать интерфейсы вместо конкретных классов, например. в объявлениях переменных, типах параметров и типах возвращаемых методов. Причина, по которой это считается лучшей практикой:

  1. Использование интерфейса для объявлений и возвращаемых типов скрывает детали реализации, что упрощает их изменение в будущем. Например, мы можем обнаружить, что код работает лучше, используя LinkedList вместо ArrayList. Теперь мы можем легко сделать это изменение в одном месте, именно там, где создается список. Эта практика особенно важна для типов параметров метода и возвращаемых методов, поэтому внешние пользователи класса не увидят детали реализации вашего класса и могут свободно изменять ее, не затрагивая их код.

  2. Используя интерфейс, будущему сопровождающему может быть понятнее, что этому классу нужен какой-то List, но ему конкретно не нужен ArrayList. Если этот класс опирается на какое-то ArrayList -специфическое свойство, т. Е. Ему нужно использовать метод ArrayList, то использование ArrayList<Example> examples = ... вместо List<Example> examples = ... может указывать на то, что этот код опирается на что-то конкретное для ArrayList .

  3. Это может упростить тестирование / макет для использования более абстрактного List, чем для использования конкретного класса ArrayList.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...