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);
    // ...
}