Java 如何通过泛型使子类型元素需要特定的子类型访问者,从而使访问者模式更具可扩展性?
我将以下设置定义为:Java 如何通过泛型使子类型元素需要特定的子类型访问者,从而使访问者模式更具可扩展性?,java,generics,design-patterns,visitor,Java,Generics,Design Patterns,Visitor,我将以下设置定义为: public interface Element { public <R> R accept(Visitor<R> visitor); } public interface Visitor<R> { } class SpecificElement implements Element { @Override // ERROR: didn't ove
public interface Element {
public <R> R accept(Visitor<R> visitor);
}
public interface Visitor<R> {
}
class SpecificElement implements Element {
@Override // ERROR: didn't override accept in parent
public <R> R accept(SpecificVisitor visitor) {
return visitor.visitSpecificElement(this);
}
}
class SpecificVisitor implements Visitor<Boolean> {
public Boolean visitSpecificElement(SpecificElement element) {
return true;
}
}
更新2:我想在不放弃类型安全的情况下为元素族编写一个访问者族。请注意,元素子树使用了相同的访问者子类型。例如:
--- Element -> Visitor<R>
|
|---- SpecificElement -> SpecificVisitor<R>
| |
| |---------SpecificElementA -> SpecificVisitor<R>
| |
| |---------SpecificElementB -> SpecificVisitor<R>
|
|---- FancyElement -> FancyVisitor<R>
|
|---------FancyElementA -> FancyVisitor<R>
|
|---------FancyElementB -> FancyVisitor<R>
---元素->访问者
|
|----SpecificElement->SpecificVisitor
| |
||-------特定元素A->SpecificVisitor
| |
||-------特定元素B->SpecificVisitor
|
|----FancyElement->FancyVisitor
|
|---------FancyElementA->FancyVisitor
|
|---------FancyElementB->FancyVisitor
也许这个版本会有用
使元素接口通用
interface Element<V> {
<R> R accept(V visitor);
}
接口元素{
R接受(V访客);
}
具体内容应该是:
public class SpecificElement implements Element<SpecificVisitor> {
public <R> R accept(SpecificVisitor visitor) {
return visitor.visit();
}
}
公共类SpecificElement实现元素{
公共R接受(特定访客){
回访者;
}
}
注意,元素的泛型V不是严格类型,可以是任何类型。元素接口的实现者,可以在其中编写任何类,即使它没有实现访问者接口。这是此代码的缺点。只要您事先知道要使用的子类型,就可以完成此操作。(您使用的是访问者模式,因此您需要提前了解所有元素类型。)重要的是从下至上而不是从上而下构建
visitor
界面:
public interface ElementVisitor<R> extends SpecificVisitor<R>, FancyVisitor<R> {
}
public interface Element {
public <R> R accept(ElementVisitor<R> visitor);
}
然后我们可以定义特定的子类型访问者和元素:
public class FancyElement1 extends FancyElement {
public <R> R accept(FancyVisitor<R> visitor) {
return visitor.visit(this);
}
}
public interface FancyVisitor<R> {
public R visit(FancyElement1 e);
// ...
}
公共类FancyElement1扩展了FancyElement{
公共R接受(FancyVisitor访客){
回访者。参观(本);
}
}
公共接口幻灯器{
公众参观(Fancyelement1e);
// ...
}
…并对特定访问者重复上述操作
现在,您可以定义一个只能访问FancyElement
s的FancyVisitor
,一个只能访问SpecificElement
s的SpecificVisitor
,或者可以访问所有元素的Element访问者
。如果没有包含类型变量或更高类型的多类型边界,我不确定是否有好的解决方案,Java都不支持这两种方法。如果您提供了一些信息或示例,说明这两种方法的有用性,也许可以帮助人们找到合适的解决方法?(与没有超类的简单定义SpecificElement
和SpecificVisitor
相比。)@DanGetz目前,我倾向于认为Java不支持这一点。但是我在上面添加了更多关于我希望发生什么的解释。@DanGetz我发布了有问题的更新。你能给出一个你想编写的代码示例,它一般使用元素
或访问者
?这可能有助于找到解决方法。我是否可以限制V,使其必须是扩展接口的类型Visitor
?我现在的问题是,我的Visitor过去有一个在方法级别提供的类型参数R
<方法级的code>R
与类级的SpecificVisitor
中的?
冲突。是否有一些解决方法?请注意,accept的返回类型取决于SpecificVisitor的类型
public abstract class FancyElement implements Element {
public abstract <R> R accept(FancyVisitor<R> visitor);
public <R> R accept(ElementVisitor<R> visitor) {
return accept((FancyVisitor<R>) visitor);
}
}
public class FancyElement1 extends FancyElement {
public <R> R accept(FancyVisitor<R> visitor) {
return visitor.visit(this);
}
}
public interface FancyVisitor<R> {
public R visit(FancyElement1 e);
// ...
}