2013-06-27 3 views
1

У меня есть общий класс:Параметр типа Java скрывает общий тип?

public class Widget<COMMAND> { 
    // ... 
} 

Так что я могу создать экземпляры ему нравится:

Widget<Fizz> fizzWidget = new Widget<Fizz>(); 

Тогда у меня есть ABC BaseWidgetProcessor, что я хочу принимать Widget S любого типа:

public abstract class BaseWidgetProcessor<Widget<COMMAND>> { 
    public abstract COMMAND process(); 
} 

С конкретными impls:

public abstract class AstroWidgetProcessor<Widget<COMMAND>> { 
    @Override 
    public COMMAND process() { 
     // ... 
    } 
} 

т.д.

Проблема заключается в том, с BaseWidgetProcessor:

public abstract class BaseWidgetProcessor<Widget<COMMAND>> { 
    public abstract COMMAND process(); 
} 

Я получаю ошибку синтаксиса:

Syntax error on token(s), misplaced construct(s)

Когда я изменить его:

public abstract class BaseWidgetProcessor<Widget> { 
    public abstract COMMAND process(); 
} 

Ошибка уходит, bu t теперь я получаю предупреждение компилятора:

The type parameter Widget is hiding the type Widget

Что здесь происходит?!? Почему ошибка, а затем соответствующее предупреждение? Каков правильный (синтаксический) способ установить это?

+0

лол. Fizzwidget. «Ты, черт возьми, дети, сойди с газона! –

+0

Извините, все - я сделал исправление –

+2

Попробуйте 'public abstract > BaseWidget '? – fge

ответ

2

Я думаю, что вы ищете:

public abstract class BaseWidgetProcessor<W extends Widget<C>, C> { 
    public abstract C process(W widget); 
} 

Я добавил W widget в качестве аргумента, чтобы показать немного лучше использование.

Теперь давайте предположим, что у вас есть виджет с именем CoolWidget:

public class CoolWidget extends Widget<Integer> {} 

Объявить CoolWidgetProcessor вы должны сделать:

public class CoolWidgetProcessor extends BaseWidgetProcessor<CoolWidget, Integer> { 
    @Override 
    public Integer process(CoolWidget widget) { 
     // ... 
    } 
} 
+0

+1 Это наиболее универсальное решение, но Bohemian's предпочтительнее, если OP не нужно генерировать тип обработанных виджетов. –

2

Попробуйте это:

public abstract class BaseWidgetProcessor<COMMAND> { 

    protected Widget<COMMAND> widget; 

    public BaseWidgetProcessor(Widget<COMMAND> widget) { 
     this.widget = widget; 
    } 

    // presumably uses widget 
    public abstract COMMAND process(); 
} 
+0

Спасибо @Bohemian (+1) - это сработало. Можете ли вы объяснить, почему (мне любопытно и хотелось бы узнать дженерики лучше, чем мое нынешнее понимание). Каково логическое ощущение того, что WidgetProcessor расширяет виджет?!? Еще раз спасибо! –

+2

Действительно, в чем логический смысл FooProcessor расширить Foo? Изменить: +1 для композиционного подхода. – ignis

+0

Ну, это не имеет особого смысла, но и не относится к виджету в типе.Второй вариант (только что добавленный) работает лучше для вас? – Bohemian