繁体   English   中英

如何实现泛型类型的抽象类?

[英]How to implement an abstract class of generic type?

我担心有关二叉搜索树的Java项目。 我们被要求实现和AVL树,但也建议保持良好的抽象,以实现其他类型的树(如红黑树)。 我决定使用abstract BsNode类(Bs =二进制搜索)和abstract BsTree类,并使用AvlTreeAvlNode以下列方式实现它们:

public abstract class BsNode<T extends BsNode> {
    T parent
    T left
    T right
    ...
}

public abstract class BsTree<T extends BsNode> {
    T root
    ...
}

public class AvlNode extends BsNode<AvlNode> {
    int balance;
    ...
}

public class AvlTree<AvlNode> {
    private void rotate(int direction);
    ...
}

这会导致两个问题:首先, BsNode不需要接收它的继承者类型。 其次,这为这样的事情开启了可能性:

public class RedBlackNode extends BsNode<AvlNode> {
    ...
}

要么

RedBlackNode myRoot = new RedBlackNode<AvlNode>();

这些不应该被允许。 如何在BsNode强制使用继承类(意味着保持parent和子类指向实现类的类型)而不是传递T泛型变量?

正如评论中所提到的,这不可能在编译时强制执行。 有一种技巧可以在运行时强制它失败。

您要做的是请求实现类将自己的类型参数类传递给抽象构造函数,并使用type-parameter类键入参数。

父类构造函数验证这个类确实是与类型参数对应的类相同的类。

abstract class BsNode<T extends BsNode<T>> {

   protected BsNode(final Class<T> clazz) {
       if (!this.getClass().equals(clazz)) 
          throw new IllegalArgumentException("invalid mixture of node types");
   } 
}

class AvlNode extends BsNode<AvlNode> {

   public AvlNode() {
        super(AvlNode.class); // works!!!
   }

}

class RBNode extends BsNode<AvlNode> {

   public RBNode() {
       // two possible super calls:
       super(AvlNode.class); // fails at run-time.
       // or
       super(RBNode.class); // fail at compilation-time.
   }
}

如果您有一个正式的构建过程作为包含测试的软件的一部分,那么将约束检查留出生产代码(节省计算时间)并将其作为单元测试的一部分可能更有意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM