Я новичок в программировании, и я изучаю Java. Мне просто интересно, почему я должен использовать интерфейс, когда есть только один класс реализации?
Почему я должен использовать интерфейс, если существует только один класс реализации?
Ответ 1
Вы делаете это, чтобы другие не могли получить доступ к вашему типу реализации. Например, вы можете скрыть свой тип реализации внутри библиотеки, предоставить доступ к типу пакета и вернуть экземпляр вашего интерфейса пользователям вашей библиотеки:
// This is what the users of your library know about the class
// that does the work:
public interface SomeInterface {
void doSomethingUseful();
void doSomethingElse();
}
// This is the class itself, which is hidden from your clients
class MyImplementation implements SomeInterface {
private SomeDependency dependency = new SomeDependency();
public void doSomethingUseful() {
...
}
public void doSomethingElse() {
...
}
}
Ваши клиенты получают такие объекты:
public class MyFactory {
static SomeInterface make() {
// MyFactory can see MyImplementation
return new MyImplementation();
}
}
Этот трюк становится полезным, когда реализация использует множество библиотек. Вы эффективно отключаете интерфейс своей библиотеки от ее реализации, чтобы пользователю не нужно было знать о зависимостях, внутренних для вашей библиотеки.
Ответ 2
Одна из причин заключается в поддержании принципа open/closed, который гласит, что ваш код должен быть открыт для расширения, но закрыт для модификации. Хотя у вас есть только один класс внедрения, вероятность того, что вам понадобится другой класс реализации с течением времени. Если вы предварительно извлечете реализацию в интерфейс, вам просто нужно написать другой класс реализации, т.е. Вам не нужно модифицировать отлично работающий фрагмент кода, устраняя риск появления ошибок.
Ответ 3
Он может предоставить вам гибкость для добавления дополнительных реализаций в будущем без изменения кода клиента, который ссылается на интерфейс.
Другим примером того, когда может быть полезно, является симуляция множественного наследования в Java, когда это необходимо. Например, предположим, что у вас есть интерфейс MyInterface
и реализация:
public interface MyInterface {
void aMethod1();
void aMethod2();
}
class MyInterfaceImpl implements MyInterface {
public void aMethod1() {...}
public void aMethod2() {...}
}
У вас также есть несвязанный класс со своей собственной иерархией:
public class SomeClass extends SomeOtherClass {
...
}
Теперь вы хотите сделать SomeClass
типом MyInterface
, но вы также хотите наследовать весь код, который уже существует в MyInterfaceImpl
. Поскольку вы не можете расширять оба SomeOtherClass
и MyInterfaceImpl
, вы можете реализовать интерфейс и использовать делегирование:
public class SomeClass extends SomeOtherClass implements MyInterface {
private MyInterface myInterface = new MyInterfaceImpl();
public void aMethod1() {
myInterface.aMethod1();
}
public void aMethod2() {
myInterface.aMethod2();
}
...
}
Ответ 4
Соблюдать принцип разделения интерфейса.
Решение о создании интерфейса не должно основываться на количестве реализующих классов, а скорее на количестве различных способов использования этого объекта. Каждый способ использования объекта представлен интерфейсом, определенным с помощью кода, который его использует. Скажите, что ваш объект должен храниться в памяти, в коллекциях, которые хранят объекты в порядке. Тот же объект, а также должен храниться в некотором постоянном хранилище.
Предположим, что вы сначала выполняете персистентность. То, что требуется системе хранения, является уникальным идентификатором для сохраняемых объектов. Вы создаете интерфейс, например Storable, с помощью метода getUniqueId. Затем вы реализуете хранилище.
Затем вы реализуете коллекцию. Вы определяете, что коллекция требует от хранимых объектов в интерфейсе, например Comparable, с методом compareTo. Затем вы можете реализовать коллекцию с зависимостью от Comparable.
Класс, который вы хотите определить, будет реализовывать оба интерфейса.
Если класс, который вы определяете, реализует единый интерфейс, этот интерфейс должен будет представлять потребности системы сбора и хранения. Это вызовет, например:
-
модульные тесты для коллекции должны быть записаны с объектами, которые реализуют Storable, добавляя уровень сложности.
-
Если возникнет необходимость позже отобразить объект, вам придется добавить методы, необходимые для отображения кода, в один интерфейс и изменить тесты для сбора и хранения, чтобы также реализовать методы, необходимые для отображения.
Я говорю о влиянии на тестовый код здесь. Проблема больше, если другие объекты уровня производства нуждаются в хранении и не отображаются. Чем больше проект, тем больше будет проблема, созданная несоблюдением принципа разделения сегрегации.
Ответ 5
Интерфейсы могут быть реализованы несколькими классами. Нет правила, что только один класс может их реализовать. Интерфейсы обеспечивают абстракцию java.
http://www.tutorialspoint.com/java/java_interfaces.htm Вы можете получить дополнительную информацию об интерфейсах из этой ссылки.