Конкретный пример, который я использовал студентам, заключается в том, что они должны писать
List myList = new ArrayList(); // programming to the List interface
вместо
ArrayList myList = new ArrayList(); // this is bad
. Они выглядят точно так же в короткой программе, но если вы продолжаете использовать myList
100 раз в своей программе, вы можете начать видеть разницу. Первая декларация гарантирует, что вы вызываете только методы на myList
, которые определены интерфейсом List
(поэтому нет специальных методов ArrayList
). Если вы запрограммировали интерфейс таким образом, позже вы можете решить, что вам действительно нужно
List myList = new TreeList();
, и вам нужно только изменить код в этом месте. Вы уже знаете, что остальная часть вашего кода не делает ничего, что будет нарушено, изменив реализацию , поскольку вы запрограммировали интерфейс .
Выгоды еще более очевидны (я думаю), когда вы говорите о параметрах метода и возвращаемых значениях. Возьмем это, например:
public ArrayList doSomething(HashMap map);
Это объявление метода связывает вас с двумя конкретными реализациями (ArrayList
и HashMap
). Как только этот метод вызывается из другого кода, любые изменения этих типов, вероятно, означают, что вам также придется изменить код вызова. Было бы лучше запрограммировать интерфейсы.
public List doSomething(Map map);
Теперь не имеет значения, какой тип List
вы возвращаете или какой Map
передается в качестве параметра. Изменения, внесенные вами в метод doSomething
, не заставят вас изменить код вызова.
Список выходных выражений после
blockquote>SELECT
может быть пустым, создавая таблицу результатов с нулевым столбцом. Это недопустимый синтаксис в соответствии со стандартом SQL. PostgreSQL позволяет поддерживать соответствие таблиц с нулевым столбцом. Тем не менее, пустой список не разрешен, если используетсяDISTINCT
.Возможность таблиц с нулевым столбцом является побочным эффектом наследования таблицы, если я не ошибаюсь. Об этом говорили в списках рассылки Postgres (но я не могу найти их прямо сейчас)