Я новичок в программировании, и я изучаю Java. Мне просто интересно, почему я должен использовать интерфейс, если есть только один класс реализации?Почему я должен использовать интерфейс, если есть только один класс реализации?
ответ
Вы делаете это, чтобы запретить другим пользователям доступ к вашему реализующий тип. Например, вы можете скрыть свой реализующий тип внутри библиотеки, дать доступ к типу пакетов, и возвращает экземпляр вашего интерфейса для пользователей библиотеки:
// 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();
}
}
Этот трюк становится полезным, когда реализация использует множество библиотек. Вы эффективно отключаете интерфейс своей библиотеки от ее реализации, чтобы пользователю не нужно было знать о зависимостях, внутренних для вашей библиотеки.
Я не вижу разницы между передачей пользователю интерфейса и передачей пользователю класса реализации. «Внешний вид» - то же самое ... – Nitek
@Nitek: вот пример, решаемый этим, где OP хочет разоблачить публичные методы тестов, которые он не хочет выставлять конечному пользователю: http://stackoverflow.com/a/6913509/217324 –
@Nitek Это не о внешнем виде, а о том, чтобы изолировать пользователей вашей библиотеки от вещей, которые они не должны видеть. – dasblinkenlight
Интерфейсы могут быть реализованы несколькими классами. Нет правила, что только один класс может их реализовать. Интерфейсы обеспечивают абстракцию java.
http://www.tutorialspoint.com/java/java_interfaces.htm Вы можете получить более подробную информацию об интерфейсах по этой ссылке
Это ссылка «только ответ», который считается ошибочным в StackOverflow, потому что ссылки идут плохо. Спросите себя, насколько хорошо ответ будет без ссылки. Если вы не готовы сделать ответ достаточно самодостаточным, вместо этого он должен быть комментарием. –
Я не думаю, что искатель считает, что вы ограничены в одном классе реализации. Я думаю, что они больше задавались вопросом, почему кто-то разделил интерфейс в случае, когда у них был только один класс реализации. –
Одна из причин заключается в поддержании принципа открытого/закрытого состояния, в котором говорится, что ваш код должен быть открыт для расширения, но закрыт для модификации. Хотя у вас есть только один класс внедрения, вероятность того, что вам понадобится другой класс реализации с течением времени. Если вы предварительно извлечете реализацию в интерфейс, вам просто нужно написать другой класс реализации, т. Е. Вам не нужно модифицировать отлично работающий фрагмент кода, устраняя риск появления ошибок.
Это может предоставить вам гибкость для добавления дополнительных реализаций в будущем без изменения кода клиента, который ссылается на интерфейс.
Другим примером того, когда может быть полезно, является симуляция множественного наследования в 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();
}
...
}
Уважать интерфейс сегрегация Принцип.
Решение о создании интерфейса не должно основываться на количестве реализующих классов, а на количестве различных способов использования этого объекта. Каждый способ использования объекта представлен интерфейсом, определенным с помощью кода, который его использует. Скажите, что ваш объект должен храниться в памяти, в коллекциях, которые хранят объекты в порядке. Тот же объект, а также должен храниться в некотором постоянном хранилище.
Предположим, что вы сначала выполняете персистентность. То, что требуется системе хранения, является уникальным идентификатором для сохраняемых объектов.Вы создаете интерфейс, например Storable, с помощью метода getUniqueId. Затем вы реализуете хранилище.
Затем вы реализуете коллекцию. Вы определяете, что коллекция требует от хранимых объектов в интерфейсе, например Comparable, с методом compareTo. Затем вы можете реализовать коллекцию с зависимостью от Comparable.
Класс, который вы хотите определить, будет реализовывать оба интерфейса.
Если класс, который вы определяете, реализует единый интерфейс, этот интерфейс должен будет представлять потребности системы сбора и хранения. Это может вызвать, например:
модульных тестов для сбора должны быть написаны с объектами, которые реализуют Storable, добавляя уровень сложности.
Если возникнет необходимость позже, чтобы отобразить объект, вам необходимо будет добавить методы, необходимые для отображения кода, в один интерфейс и изменить тесты для сбора и хранения, чтобы также реализовать методы, необходимые для отображения.
Здесь я расскажу о влиянии на тестовый код. Проблема больше, если другие объекты уровня производства нуждаются в хранении и не отображаются. Чем больше проект, тем больше будет проблема, созданная несоблюдением принципа разделения сегрегации.
Открыто, потому что этот вопрос значительно более конкретный, чем предполагаемый дубликат. – dasblinkenlight
Для записи, если кто-то заинтересован в том, что такое «предполагаемый дубликат», как и я: http://stackoverflow.com/questions/1321122/what-is-an-interface-in-java –