Я пользуюсь библиотекой GWT. Существует базовый класс под названием Виджет, которому наследовались все Виджеты. Некоторые Виджеты реализуют определенные интерфейсы (например, HasText), другие не делают. Иногда я хочу гарантировать, что что-то передаваемое как аргумент функции имеет определенный класс И реализует определенный интерфейс.
Например, я хочу иметь функцию, которая берет аргумент X, где X имеет Виджет типа класса И интерфейсного типа 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? Если существует несколько способов сделать так, есть ли предпочтительный/лучше путь?
Спасибо за оба ваших решения. В конце концов, я решил, что лучшим решением будет просто указать ограниченные типы в верхней части определения класса. Например, я использовал форму
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.
}
Я выбрал это решение по нескольким причинам.
Объявление ограниченных типов в заголовке класса - это лучшее решение, с которым я сталкивался. Мне было бы интересно узнать, есть ли способ постоянно объявлять (чтобы к нему можно было обращаться в разных классах) ограниченные типы, а не объявлять их в каждом классе.
Здесь вы могли бы использовать универсальный метод:
public <T extends Widget & HasText> void fx(T x)
Компилятор автоматически определит тип T, поэтому при вызове метода не требуется дополнительного синтаксиса.
Я бы справился с этим, добавив метод к интерфейсу HasText для возврата виджета, и реализация просто вернет это.
public class MyClass extends Widget implements HasText {
@Override
public Widget getMyWidget() {
return this;
}
}
Итак, если методу нужен виджет, вы просто вызываете метод getMyWidget () HasText. Он действительно создает некоторый шаблон, но помогает при проверке статического типа.
Если вас не слишком заботит проверка статического типа, вы можете просто иметь контракт (оператор в JavaDoc), что интерфейс HasText предназначен только для реализации в виджетах, а затем просто приводить его, когда вам понадобится Виджет.
Тогда ваш метод будет выглядеть так:
public void fx(HasText text) //...