generics和访客模式

我对访问者模式和generics有问题。 我有一些抽象的class级,他们的孩子将被访问。 看看这段代码:

public abstract class Element extends SomeSuperClass { public void accept(Visitor v) { v.visit(this); } } public interface Visitor { void visit(T element); } 

所以我的想法是:我有一些类层次结构(例如, ElementSomeSuperClass的子类)。 我有一些通用的Visitor界面来访问这个层次结构。 现在在这个层次结构的中间是Element类,它是抽象的并且拥有它自己的子类。

现在我希望Element接受其子类的所有访问者,这就是我放这行的原因:

 public void accept(Visitor v) 

但现在我收到错误:

方法访问( capture#1-of ? extends Element )类型为Visitor Visitor不适用于参数( Element )。

我明白了? extends Element ? extends Element不是Element 。 我的问题是:我可以用不同的方式表达我的想法吗? 或者我在这种情况下错过了generics的想法?

请注意, 中的可以是与Element完全无关的类型,并且编译器必须确保visit(T t)对每个可能的T

您调用的代码为Visitor.visit(Element e) ,但相关访问者可能是Visitor 。 这没有意义。

我认为“ Element必须接受其子类的所有访问者”的要求没有意义:访问者必须至少能够访问Element 及其所有子类 。 那将是一个Visitor

构造accept(Visitor v)意味着v可以是T extends Element任何此类Visitor 。 这并不意味着访客本身将属于Visitor Visitor 。 实际上,Java中甚至不存在这样的东西。 每个访问者都将具有与之关联的特定类型参数,而不是通配符。

那不行 – 参观者? extends Element ? extends Element可能需要能够访问Element没有或不知道的数据(属性/方法,…)。

你不能得到一个访问者,它应该访问扩展Element对象,以便必须能够访问一个直接Element或者另一个完全独立的Element子类。

我认为你想要做的事情没有多大意义。 使Visitorgenerics是无用的: accept()方法必须将特定的访问者接口作为参数,以便Element子类可以调用visit()特定重载。

 interface Visitor { void visit(Element e); void visit(SubElement e); } class Element { public void accept(Visitor v) { v.visit(this); } } class SubElement { public void accept(Visitor v) { v.visit(this); } } class ElementVisitor implements Visitor { public void visit(Element e) {} public void visit(SubElement e) {} } 

请注意, Visitor接口必须知道Element层次结构中需要自定义visit()实现的所有类。

编写它的最常用方法是:

 public void accept(Visitor v) { v.visit(this); } 

这样,即使是一个Visitor也可以工作(为什么不应该这样)。

记住PECS(生产商extends ,消费者super )。 访客是消费者,所以它应该是super