Каковы преимущества объявления объекта как интерфейса?
Возможный дубликат:
Что означает "программировать интерфейс" ?
Я заметил, что некоторым людям нравится объявлять объект как один из интерфейсов, который он реализует , хотя в рамках этой переменной нет необходимости рассматривать его как интерфейс, например. нет внешнего API, который ожидает интерфейс.
Например:
Map<String, Object> someMap = new HashMap<String, Object>();
Или вы можете просто сделать
HashMap<String, Object> someMap = new HashMap<String, Object>();
и вообще не импортировать java.util.Map
.
В чем преимущества объявления его через интерфейс (сначала выше) в отличие от самого класса (второй выше)?
Спасибо
Ответы
Ответ 1
Если переменная не используется позже, нет никакого преимущества/недостатка. Причина, по которой вы должны использовать интерфейс, а не объект, - это обеспечить большую гибкость, но если эта переменная не используется, то нет никакой разницы в производительности.
Ответ 2
Интерфейс, такой как Map<A, B>
, объявляет, что может сделать объект. С другой стороны, класс, такой как HashMap<A, B>
, определяет, как объект выполняет то, что объявляет интерфейс.
Если вы объявляете переменную (или поле или что-то еще) Map<A, B>
, вы заявляете, что ваш код зависит только от контракта, определенного этим интерфейсом, он не зависит от специфики реализации.
Если вы объявите его HashMap<A, B>
, следует понимать, что вам нужна эта конкретная версия карты (по какой-либо причине), и ее нельзя заменить для чего-то еще.
Я, как правило, не люблю общие ответы типа "потому что вы можете изменить реализацию" просто потому, что после многих лет практики вы увидите, что это произойдет не так часто, как это, и основные преимущества действительно тонкое (но ясное) выражение ваших намерений.
Ответ 3
Поскольку он не является частью API, это детализация реализации. Лучше быть конкретным в реализациях, здесь нет смысла быть абстрактным.
мой предыдущий ответ
Использовать интерфейс или тип для определения переменной в java?
Ответ 4
Если вы используете Map<String, Object> someMap
, вы разрабатываете интерфейс, а не реализацию. Таким образом, вы можете легко переключаться между другими реализациями.
Итак, ваш Map
может указывать на HashMap
, LinkedHashMap
или любой другой объект, который является подклассом Map
.
Итак, если у вас есть: -
Map<String, Integer> someMap = new HashMap<>();
Вы можете изменить реализацию позже (если хотите), чтобы указать на LinkedHashMap
: -
someMap = new LinkedHashMap<>();
Если вы используете HashMap
в LHS, вы можете указать только объект типа HashMap
..
Но, как таковой, нет никакой разницы в производительности. Но всегда рекомендуется design
использовать interface
, а не implementation
..
Ответ 5
Интерфейс определяет, какой метод должен реализовывать класс.
Таким образом - если вы хотите вызвать метод, определенный интерфейсом, вам не нужно знать точный тип класса объекта, вам нужно только знать, что он реализует определенный интерфейс.
Пример:
interface Printer {
public void print(String text);
}
class FilePrinter implements Printer {
public void print(String text) {
//append the text to a file
}
}
class ScreenPrinter implements Printer {
public void print(String text) {
//write the text on the screen
}
}
class SomeClass {
public printSomething(Printer myPrinter) {
myPrinter.print("Hello");
}
}
Если вы вызываете SomeClass.printSomething(...), не имеет значения, передаете ли вы экземпляр FilePrinter или ScreenPrinter, потому что метод просто не волнует. Он знает, что объект реализует интерфейс Printer, а также реализует его методы.
Другим важным моментом в интерфейсах является то, что класс может реализовывать несколько интерфейсов.