Почему я должен использовать общие классы вместо конкретных классов

Недавно я прочитал, что я должен использовать общие классы вместо конкретных классов при программировании. Я не могу понять, почему это предлагается.

пример: допустим, у нас есть класс MyPanel, который наследуется от JPanel. MyPanel - не наследуемый метод с именем getLastChild.

вместо:

MyPanel panel = new MyPanel():
Component last = panel.getLastChild();

предлагается сделать это:

JPanel panel = new MyPanel();
Component last = ((MyPanel)panel).getLastChild();

Я не понимаю, почему я должен выбрать второй.

4 ответа

Вы правы, этот пример действительно не имеет смысла.

Общее правило заключается в том, что вы должны использовать самый общий класс, который все еще имеет соответствующую функциональность. Таким образом, вы позволяете себе изменять конкретный класс, который вы используете, и продолжаете работать с остальной частью программы. Например, рассмотрим JDK Collections.sort(List), Тот же самый вызов метода может использоваться с ArrayList, LinkedListили любой другой List - он не заботится о специфике того, как этот список реализован, просто о том, что это список.

Ваш пример, однако, отличается. Если вам нужно позвонить MyPanel.getLastChild()вы наверняка заботитесь о MyPanel - вы не можете просто использовать любой другой JPanel, Поскольку у вас уже есть эта зависимость, нет смысла объявлять вашу переменную как JPanel и удручает это просто позвонить getLastChild(),

Хорошим примером будет:

List<Integer> list = new ArrayList<Integer>;

вместо

ArrayList<Integer> list = new ArrayList<Integer>;

Зачем?

Это дает вам больше гибкости и обобщает ваш код бесплатно.

объяснение

Всякий раз, когда вы хотите передать list вы будете использовать List вместо ArrayList, Например, у вас есть метод:

public void doSomething(List<Integer> list)

Позже вы можете легко изменить свою реализацию, если вы, например, понимаете, что LinkedList это лучший выбор.

Теперь вы можете разработать полезный метод, который работает с JPanels. Давайте назовем это foo(JPanel p),

Теперь вы можете использовать его с любым JPanel в том числе MyPanel, Но почему? Вы можете определить метод следующим образом: foo(MyPanel p) и использовать его с MyPanel пока вы не разработаете вторую панель, которая называется OtherPanel, Вы не можете отправить это OtherPanel в foo() который работает с MyPanel только.

Однако первая (общая) версия foo() может использоваться как для любого другого класса, который расширяется JPanel и разработано вами, мной или любым другим программистом.

Я надеюсь, что этого простого примера достаточно, чтобы понять необходимость обобщения.

Этот второй приносит большую гибкость. Если вы объявляете панель типа MyPanel, то она может быть ТОЛЬКО MyPanel (или классами, которые наследуются от MyPanel), тогда как если вы объявляете панель как тип JPanel, это может быть общий JPanel ИЛИ любой подкласс JPanel (включая MyPanel). Это делает ваш код более переносимым и простым для редактирования в будущем. Ваш компонент может быть только MyPanel сейчас, но что, если это изменится позже?

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