Дженерики по сравнению с интерфейсами

Я перешел от Java 1.4 (предыдущая компания) к Java 1.6 (новая компания). Что я заметил, что в случае 1,4 большинство собственных платформ было определено с помощью интерфейсов и шаблонных шаблонов, тогда как с 1,6 большинство платформ определяется вокруг дженериков.

В то время как я все еще пытаюсь получить власть вокруг Дженериков, мой вопрос - действительно ли это - правильный подход дизайна? Интерфейсы делают Ваш дизайн более гибким/разъединяющим. Принимая во внимание, что Дженерики, безопасность типов реализации и осуществляют Вас для раздавания определенного типа класса. Действительно не помогает в разъединении Вашего кода. Это корректно?

Один пример -

public MyWizard extends SignupWizard<SignupSection, SignupObject, SignupListener, SignupView>{
}

вместо этого дизайн был бы более гибким, если бы это было..

public interface Wizardable{
  public SignableSection getSection();
  public SignableObject getSignableObject();
...
}

public MyWizard implements Wizardable{
....
}
11
задан Win Man 24 February 2010 в 22:31
поделиться

4 ответа

Я бы не сказал, что что-то было чем-то вроде интерфейсов и дженериков, у каждого из которых свои потребности и разные способы использования. Использование общих параметров способом, указанным в исходном сообщении, служит нескольким целям. Он позволяет разработчикам определять базовые классы, составляющие типы объектов поля класса. Используя это, разработчик может принять объекты класса в качестве параметров, для которых он может использовать отражение для создания фактических объектов и установки полей, или просто принять весь объект для установки в первую очередь. Проблема, которая связана с необходимостью объектов класса вместо выполнения new T () или подобного, известна как стирание типа .

Еще одним преимуществом использования универсальных шаблонов является то, что вам не нужно постоянно приводить типы при использовании полей или методов из суперкласса - вы лично знаете их типы, но в Java нигде не хранится такая информация о типах. Дополнительным преимуществом является то, что все ваши методы получения / установки могут использовать общие параметры и предоставлять более разумный фронт другим объектам, которые полагаются на тот факт, что вы настроили специализированные поля в вышеупомянутом объекте.

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

Как я упоминал в комментарии, любые подклассы устанавливают эти параметры типа и ничего не предоставляют пользователю. Таким образом, у вас может быть что-то вроде class MegaSignupWizard extends RegistrationWizard , и все остается совершенно корректным с MegaSignupWizard , имеющим доступ к специализированным методам в классах без необходимости использования каких-либо специальных методов в классах. В ролях. Вот это круто :)

5
ответ дан 3 December 2019 в 10:03
поделиться

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

3
ответ дан 3 December 2019 в 10:03
поделиться

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

Я также не уверен, что ваше вышеприведенное использование выглядит хорошо. Если вы расширяетесь от объекта или реализуете интерфейс, вы не захотите передавать объекты таким образом. Дженерики используются для реализации класса с абстрактным типом, например, коллекции, который может действовать на что угодно. Что произойдет, если я передам SignupWizard, что вполне допустимо?

Для этой конкретной идеи, возможно, вы действительно хотите использовать интерфейсы. Пусть интерфейс определяет wizardaction, каждый объект реализует его, а mywizard сможет .addaction(int position, wizardaction action). На самом деле это определенно проблема интерфейсов.

Я соглашусь с остальными - дженерики используются, когда они нужны библиотекам.

0
ответ дан 3 December 2019 в 10:03
поделиться

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

С помощью универсальных типов можно уменьшить некоторое дублирование кода и повысить безопасность типов, когда у вас есть один интерфейс с параметрами универсального типа, и один и тот же интерфейс будет работать для множества разных типов. Коллекции в пакете java.util - хороший пример того, когда можно использовать универсальные шаблоны.

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

1
ответ дан 3 December 2019 в 10:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: