почему атрибут из интерфейса объявлен в классах - PullRequest
0 голосов
/ 06 февраля 2011

Я видел, что если у меня есть интерфейс с именем interfaceABC.

Пример:

public class ABController extends AbstractCOntroller {


private interfaceABC inter;

Меня смущает, почему мы делаем объект из интерфейса, а не из класса, который его реализовал.

Ответы [ 5 ]

2 голосов
/ 06 февраля 2011
private interfaceABC inter;

Меня смущает, почему мы делаем объект из интерфейса, а не из класса, который его реализовал

Мы еще не создали объект / экземпляр .Мы просто объявили переменную для ее хранения.Мы не создаем объекты из интерфейсов (для этого нужно использовать конкретный класс), но мы часто будем использовать типы интерфейсов вместо реального конкретного класса для объявлений переменных, типов параметров метода и типов возврата метода.

Возьмем это для примера:

List<Example> examples = new ArrayList<Example>();
...
public List<Example> getExamples() { return examples; }

Использование интерфейса List здесь вместо конкретного класса ArrayList следует общепринятой наилучшей практике: по возможности использовать интерфейсы вместо конкретных классов, например, вобъявления переменных, типы параметров и типы возвращаемых методов.Причина, по которой это считается лучшей практикой:

  1. Использование интерфейса для объявлений и возвращаемых типов скрывает детали реализации, упрощая модификацию в будущем.Например, мы можем обнаружить, что код работает лучше, используя LinkedList вместо ArrayList.Теперь мы можем легко сделать это изменение в одном месте, именно там, где создается список.Эта практика особенно важна для типов параметров метода и возвращаемых методов, так что внешние пользователи класса не увидят детали реализации вашего класса и могут свободно изменять ее, не затрагивая их код.

  2. Используя интерфейс, будущему сопровождающему может быть понятнее, что этот класс нуждается в каком-то List, но ему конкретно не требуется ArrayList.Если этот класс опирается на какое-то ArrayList -специфическое свойство, т. Е. Ему нужно использовать метод ArrayList, то использование ArrayList<Example> examples = ... вместо List<Example> examples = ... может указывать на то, что этот код опирается на что-то конкретное для ArrayList.

  3. Это может упростить тестирование / макет для использования более абстрактного List, чем для использования конкретного класса ArrayList.

2 голосов
/ 06 февраля 2011

Мы не создали объект, мы сделали ссылку .

Используя ссылку на интерфейс, а не конкретный класс, мы можем поменяться местами.различная реализация интерфейса, без изменений в этом коде.Это улучшает инкапсуляцию, а также облегчает, например, тестирование (потому что мы можем использовать фиктивные объекты ).См. Также внедрение зависимостей .

1 голос
/ 06 февраля 2011

Представьте себе лавочку для упаковки подарков в магазине, где есть машина, которая обернет любую коробку.

Машина просто спроектирована и изготовлена ​​для упаковки прямоугольной коробки, не важно, есть ли в коробке шоколад или игрушечная машинка. Если бы это имело значение, машина, очевидно, имела бы недостатки.

Но даже прежде, чем вы доберетесь до этого киоска, вы должны купить этот подарок: поэтому кассир сначала сканирует штрих-код. Сканер штрих-кода является еще одним примером того же принципа: он будет сканировать что угодно, если на нем есть узнаваемый штрих-код. Сканер штрих-кода, который сканирует только газеты, будет бесполезен.

Эти наблюдения привели к концепции инкапсуляции в разработке программного обеспечения, которую вы можете увидеть в действии, когда класс ссылается на объект только через интерфейс, а не на его конкретный класс.

1 голос
/ 06 февраля 2011

Для частного поля это не имеет большого значения, так как в любом случае это деталь реализации. Многие люди по-прежнему будут использовать интерфейс везде, где только могут.

С другой стороны, поля protected (и, конечно, параметры открытых методов) образуют API, который становится намного более гибким благодаря использованию интерфейсов, поскольку это позволяет подклассам / клиентам выбирать, какой класс реализации они хотят использовать даже классы, которые они поставляют сами и которые даже не существовали при создании API.

Конечно, если у вас есть общедоступный метод или конструктор set, который устанавливает приватное поле, то вы также должны использовать тип интерфейса для поля.

1 голос
/ 06 февраля 2011

Это на самом деле очень полезно.Возьмите пример, что мы используем список.

public class A {
    private List<String> list;

    public A(List<String> list) {
        this.list = list;
    } 

}

Это позволяет классу A работать со всеми операциями, определенными интерфейсом list.Конструктор класса A теперь может давать любую реализацию без изменения кода класса A, что способствует инкапсуляции , повторному использованию кода, тестированию и т. Д.1013 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...