使用原始类型实现通用接口

时间:2010-01-31 09:23:36

标签: java generics types

我有一个通用树,泛型参数是节点存储的数据类型:

class TreeNode<D>{  
    public D data;  
    .....
}

然后一个访问者界面与树横向一起使用:

interface Visitor<D> {
    void visit(TreeNode<D> node);
}

有些访问者可以利用泛型:

class DataListCreator<D> implements Visitor<D> {
    List<D> dataList = new ArrayList<D>();
    public void visit(TreeNode<D> node) {
         dataList.add(node.data);
    }
    public List<D> getDataList() {
        return dataList;
    }

但是其他人没有,他们会更适合原始课程

class NodeCounter implements Visitor {
    private int nodeCount = 0;
    public void visit(TreeNode node) {
        nodeCount++;
    }
    public int count() {
        return nodeCount;
    }

但我不知道如何实现这最后一种情况,上面的代码不能编译,因为我必须实现 通用接口不是原始接口。我尝试过实施

Visitor<?> 

具有相同的结果。所以我的问题是,我被迫使用泛型

NodeCounter<D> 

实现访问者界面?。

感谢。

4 个答案:

答案 0 :(得分:3)

  

上面的代码不能编译

我尝试编译你的例子,它工作正常。我正在使用Java 6.你得到的编译错误是什么?

这是我成功编译的内容:

class TreeNode<D>{  
    public D data;  
}

interface Visitor<D> {
    void visit(TreeNode<D> node);
}

class NodeCounter implements Visitor {
    private int nodeCount = 0;
    public void visit(TreeNode node) {
        nodeCount++;
    }
    public int count() {
        return nodeCount;
    }
}

答案 1 :(得分:3)

Java泛型非常强大,几乎不需要原始类型。

您可能想要放入一些通配符。例如,访问者可能无需知道它正在访问的TreeNode的确切通用参数:

interface TreeNodeVisitor<D> {
    void visit(TreeNode<? extends D> node);
}

或许更好(?),TreeNode可能不需要知道访问者的确切类型。

interface TreeNode<D> {
    void accept(TreeNodeVisitor<? super D> visitor);
}

答案 2 :(得分:1)

简而言之 - 是的,你需要给通用接口一个类型参数。

你可能应该做的是,实现一个非通用的(可能是空的)接口ITreeNodeITreeNode<D>继承自。{1}}。任何不需要是通用的方法都会在此intercace中声明。然后,为IVisitor执行相同的操作,NodeCounter可以继承非通用Visitor接口。

简短示意图:

ITreeNode
ITreeNode<D> implements TreeNode

IVisitor
IVisitor<D> implements IVisitor

NodeCounter implements IVisitor

(注意:我使用C#约定来为I添加前缀。NodeCounter是一个类,而其他是接口......)

答案 3 :(得分:1)

Java Generics明确设计为使用称为Erasure的技术与原始类型互操作。

所以你所描述的情况是直接支持的,应该编译好:

class TreeNode<D>{
    public D data;  
}

interface Visitor<D> {
    void visit(TreeNode<D> node);
}

class NodeCounter implements Visitor {
    private int nodeCount = 0;
    public void visit(TreeNode node) {
        nodeCount++;
    }
    public int count() {
        return nodeCount;
    }
}