Могу ли я гарантировать печать на интерфейсе класса И аргумента? - PullRequest
5 голосов
/ 19 февраля 2010

Я использую библиотеку GWT. Существует базовый класс Widget, от которого наследуются все виджеты. Некоторые виджеты реализуют определенные интерфейсы (например, HasText), другие - нет. Иногда я хочу гарантировать, что что-то, передаваемое в качестве аргумента функции, имеет определенный класс И реализует определенный интерфейс.

Например, я хочу иметь функцию, которая принимает аргумент X, где X имеет тип класса Widget И типа интерфейса HasText. Я хочу иметь такое поведение, потому что в контейнеры макета могут быть добавлены только виджеты, а HasText определяет полный набор поведений, которые мне действительно нужны из указанного виджета.


В форме псевдокода это может быть:

public void fx(I_AM_A_Widget_AND_IMPLEMENT_INTERFACE_HasText x){
    //do stuff with x, which is guaranteed to be a Widget AND implement HasText
}

Это возможно в Java? Если есть несколько способов сделать это, есть ли предпочтительный / лучший способ?

Ответы [ 3 ]

7 голосов
/ 19 февраля 2010

Вы можете использовать общий метод здесь:

public <T extends Widget & HasText> void fx(T x)

Компилятор автоматически определит тип T, поэтому при вызове метода не будет никакого дополнительного синтаксиса.

1 голос
/ 19 февраля 2010

Я бы справился с этим, добавив метод в интерфейс HasText для возврата виджета, а реализация просто вернула бы его.

    public class MyClass extends Widget implements HasText {

            @Override
            public Widget getMyWidget() {
                return this;
            }
    }

Так что если методу нужен виджет, вы простовызовите метод getMyWidget () из HasText.Он действительно создает некоторый шаблон, но он помогает с проверкой статического типа.

Если вам не слишком важна проверка статического типа, вы могли бы просто иметь контракт (утверждение в JavaDoc), что HasTextИнтерфейс предназначен только для реализации на виджетах, а затем просто вызывается, когда вам нужен виджет.

Тогда ваш метод выглядит просто как

 public void fx(HasText text) //...
0 голосов
/ 20 февраля 2010

Спасибо за ваши решения. В конце концов я решил, что лучшим решением будет просто указать ограниченные типы в начале определения класса. Например, я использовал форму

public class Example<Editable extends Widget & HasText> {
  private Editable editor = null;

  //do stuff in various methods (including the constructor) with the 
  //editor variable and the Editable type.
}

Я выбрал это решение по нескольким причинам.

  1. Оба вышеупомянутых решения требуют использования методов (шаблон), которые на самом деле не относятся к бизнес-функциям, а связаны с обходом ограничений языка.
  2. Anon, ваше решение верное, но у меня проблема в том, что я не могу объявить переменную, которая будет содержать ссылку на универсальный объект, который возвращает ваш метод. Я полагаю, что это так, потому что общий объект, возвращаемый из вашего метода, существует только на уровне метода, а не класса. Возможно, я пропустил некоторый синтаксис, который позволил бы мне объявлять переменные, которые имеют общие свойства?
  3. Ишай, ваше решение тоже работает, но у меня возникает проблема с объявлением отдельного метода в каждом интерфейсе, для которого я хочу гарантировать поддержку, это казалось громоздким.
  4. Эти ограниченные типы, объявленные в классе "header", должны быть объявлены только один раз. Это кажется самым кратким объявлением общих ограниченных типов, доступных в Java.
  5. Вы можете объявить более одного ограниченного типа в классе "header".
  6. Если вы используете этот метод исключительно, все потенциальные ограниченные типы объявляются в одном и том же месте вашего кода.

Объявление ограниченных типов в заголовке класса - лучшее решение, с которым я столкнулся. Мне все еще было бы интересно узнать, является ли их способом постоянно объявлять (чтобы к нему могли обращаться разные классы) ограниченный тип, а не объявлять их по классам.

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