我有Visitor模式和仿制药的问题。 我有一些抽象类,其子女都到会参观。 看看下面的代码:
public abstract class Element extends SomeSuperClass {
public void accept(Visitor<? extends Element> v) {
v.visit(this);
}
}
public interface Visitor<T extends SomeSuperClass> {
void visit(T element);
}
这样的想法是:我有一些类层次结构(如Element
是的子类SomeSuperClass
)。 我有一些通用的Visitor
接口来访问这个层次。 现在,在这个层次结构的中间是Element
类,它是抽象的,有它自己的子类。
现在我想Element
接受它的子类的所有游客,这就是为什么我把这个行:
public void accept(Visitor<? extends Element> v)
但现在我收到错误:
该方法的访问( capture#1-of ? extends Element
中的类型) Visitor<capture#1-of ? extends Element>
Visitor<capture#1-of ? extends Element>
是不适用的参数( Element
)。
我明白? extends Element
? extends Element
不是Element
。 我的问题是:我可以表达我的想法不同的方式? 还是我刚才错过了在这种情况下,仿制药的想法?
需要注意的是T
在<T extends SomeSuperClass>
可以是一种类型的完全无关的Element
和编译器必须确保对于一般的情况下visit(T t)
会为每一个可能的工作T
。
你的代码调用Visitor.visit(Element e)
但有问题的游客可以Visitor<SubElement>
。 这是没有意义的。
我认为该规定“ Element
必须接受它的子类的所有访问者”无厘头:游客必须至少能够访问Element
及其所有子类 。 这将是一个Visitor<Element>
。
该构建体accept(Visitor<? extends Element> v)
表示v
可以是任何这样的Visitor<T>
该T extends Element
。 这并不意味着游客本身将是类型的Visitor<? extends Element>
Visitor<? extends Element>
。 事实上,没有这样的事情,甚至存在于Java的。 每一位游客都会有与之相关联的特定类型的参数,而不是一个通配符。
这不能工作-的游客? extends Element
? extends Element
可能需要能够访问数据(属性/方法,...),其Element
没有或不知道的。
你不能说是应该访问对象访问者扩展Element
到一定能够访问的东西,这是一个直线Element
,甚至另一个完全独立的子Element
。
我不认为你正在试图做的是什么使多大意义。 使Visitor
一般是没用的:在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
hyerarchy需要自定义visit()
的实现。
写这将是最一般的方法:
public void accept(Visitor<? super Element> v) {
v.visit(this);
}
这样一来,即使是Visitor<Object>
将工作(为什么不要呢)。
记住佩奇(生产者extends
,消费super
)。 访问者是一个消费者,所以它应该是super
。