Я поздний участник этого вопроса, но я хочу упомянуть здесь, что строка «Программа для интерфейса, а не реализация» имела хорошее обсуждение в книге шаблонов дизайна GoF (Gang of Four).
На стр. 18:
Программа для интерфейса, а не для реализации
Не объявляйте переменные экземплярами конкретных конкретных классов. Вместо этого зафиксируйте только интерфейс, определенный абстрактным классом. Вы найдете это общей темой шаблонов проектирования в этой книге.
blockquote>и выше этого, это началось с:
Есть два преимущества манипулировать объектами исключительно с точки зрения интерфейса, определенного абстрактными классами:
blockquote>
- Клиенты не знают о конкретных типах объектов, которые они используют, если объекты соответствуют интерфейсу, который ожидают клиенты.
- Клиенты не знают о классах, которые реализуют эти объекты. Клиенты знают только об абстрактном классе (ов), определяющем интерфейс.
Так, другими словами, не записывайте его в свои классы, чтобы он имел метод
quack()
для уток, а затем методbark()
для собак, поскольку они слишком специфичны для конкретной реализации класса (или подкласса). Вместо этого напишите метод, используя имена, которые являются достаточно общими для использования в базовом классе, напримерgiveSound()
илиmove()
, чтобы их можно было использовать для уток, собак или даже автомобилей, а затем для клиента вашего классы могут просто сказать.giveSound()
, а не думать о том, использовать лиquack()
илиbark()
или даже определить тип перед выдачей правильного сообщения, которое должно быть отправлено объекту.
Это правило указано в Спецификация языка Java :
Некоторые типы выражений могут использоваться в качестве операторов, следуя за ними с точкой с запятой.
ExpressionStatement:
- StatementExpression;
StatementExpression:
blockquote>
- Назначение
- PreIncrementExpression
]- PreDecrementExpression
- PostIncrementExpression
- PostDecrementExpression
- MethodInvocation
- ClassInstanceCreationExpression
Вы видите, что вызов конструктора является выражением. Но строковое литераловое или математическое выражение не является.
Вы ищете разницу между выражениями и выражениями-выражениями. Такие выражения, как myVoid();
, могут быть записаны как утверждение: это недействительные методы и т. Д. (Это та часть, которую вы знаете). Выражения, такие как (3 + 2);
и "arbitraryString"
, не имеют побочных эффектов. Их можно рассматривать только как значение, поскольку код не выполняется. Операторы выражения, такие как new Object();
, могут иметь побочные эффекты и выполнять код, и иногда вы просто хотите, чтобы этот код выполнялся и игнорировал возвращаемое значение. Поэтому компилятор допускает это.
Создание объекта или вызова или метода может иметь побочные эффекты, я думаю, что это основная причина этого, тогда как ничего не произойдет с арифметическим выражением.
Линия, содержащая только
new Object();
или, если быть более точным,
new SomeClass();
приемлема, поскольку код конструктора SomeClass()
может быть все, что мы хотим.
Но в случае строк, содержащих только
"foo";
или
2;//or (2+3);
, компилятор знает, что помимо создания / повторного использования строкового литерала или целочисленного литерала этот код doesn не делайте ничего другого, что означает, что это, вероятно, какая-то ошибка программиста, поэтому компилятор не может ее принять.