gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:47:28 25 4
gpt4 key购买 nike

我正在研究一个关于二叉搜索树的 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 和 children 指针指向实现该类的类型)而不是传递 T 通用变量?

最佳答案

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

你所做的是请求实现类将它们自己的类型参数类传递给抽象构造函数,并带有一个用类型参数类键入的参数。

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

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.
}
}

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

关于java - 如何实现泛型的抽象类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50419463/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com