1

我正在尝试创建一个为 instanceof 对象Visitor<T>返回某个值的对象。strategy它已经有效,但我无法获得Generics类型安全。我在以下代码中缺少什么:

class Base;
class Foo extends Base;
class Bar extends Base;

interface Visitor<T> {
    T visit (Foo foo);
    T visit (Bar bar);
}

interface Strategy<T> {
    void action(T obj);
}

class FooStrategy implements Strategy<Foo> {
    @Override
    void action(Foo foo) {
        //perform strategy action on foo
    }
}

//References to generic type Strategy<T> should be parameterized
class MyVisitor implements Visitor<Strategy> {

    //References to generic type Strategy<T> should be parameterized
    @Override
    Strategy visit(Foo foo) {
        return new FooStrategy();
    }

    //References to generic type MyStrategy<T> should be parameterized
    @Override
    Strategy visit(Bar bar) {
        return new BarStrategy();
    }
}

在类MyVisitoreclipse 中不断抱怨Strategy<T>应该参数化。制作这个通用构造我缺少什么typesafe

更新:

我想像这样使用它:

        Visitor<Strategy> visitor = new MyVisitor();
        Strategy strat = drawable.accept(visitor);

        //use the strategy
        Base object; //may be a Foo or Bar or whatever
        strat.action(object);
4

2 回答 2

2

您可以? extends Base在 type 参数中添加一个以表明它是您不关心的任何类型的策略,但它必须是 Base 的子类。

class MyVisitor implements Visitor<Strategy<? extends Base>> {
  @Override
  Strategy<? extends Base> visit(Foo foo) {
    return new FooStrategy();
  }
  @Override
  Strategy<? extends Base> visit(Bar bar) {
    return new BarStrategy();
  }
}

    Visitor<Strategy<? extends Base>> visitor = new MyVisitor();
    Strategy<? extends Base> strat = drawable.accept(visitor);

但是,您不能调用这样的策略:

    //use the strategy
    Base object; //may be a Foo or Bar or whatever
    strat.action(object);  // <--- error.

因为动作方法实际上有一个签名

<U extends Base> void action(U object);

即参数的类型可能需要Base 的任意子类,并且可以传递给 Base 的任意子类的唯一类型是null.

要解决这个问题,只需让 FooStrategy 和 BarStrategy 实现Strategy<Base>

class FooStrategy implements Strategy<Base> { void action(Base obj) { ... } }
class BarStrategy implements Strategy<Base> { void action(Base obj) { ... } }

class MyVisitor implements Visitor<Strategy<Base>> {
  @Override
  Strategy<Base> visit(Foo foo) {
    return new FooStrategy();
  }
  @Override
  Strategy<Base> visit(Bar bar) {
    return new BarStrategy();
  }
}

Visitor<Strategy<Base>> visitor = new MyVisitor();
Strategy<Base> strat = drawable.accept(visitor);

Base object;
strat.action(object);
于 2013-03-31T18:32:52.520 回答
0

这不是访客。即使是这样,这也不是一个正确的用途。访客使用双重调度;这没有那个。

于 2013-04-01T19:31:21.607 回答