[英]How to implement an abstract class of generic type?
我担心有关二叉搜索树的Java项目。 我们被要求实现和AVL树,但也建议保持良好的抽象,以实现其他类型的树(如红黑树)。 我决定使用abstract BsNode
类(Bs =二进制搜索)和abstract BsTree
类,并使用AvlTree
和AvlNode
以下列方式实现它们:
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.