所以基本上我有一个代表下面的二叉树的抽象类。我想创建一个名为 RBTree 的子类,它将利用 BinaryTree 中的所有抽象,包括修改内部 Node 类以采用颜色和父属性的能力。
但是我不知道 Kotlin 或 Java 是如何做到这一点的(如果它们可以的话)。
我能做到的最接近的是创建一个新类,它是 Node 的子类,它破坏了 BinaryTree 中的许多其他抽象,因为我们必须使用不同的 Node 对象。尝试重新定义 Node 是行不通的。如果你知道如何用 java 来做这件事也可以。
class RBTree<E : Comparable<E>> : BinaryTree<E>(){
override val rootNode: RBNode<E> = TODO()
override fun addNode(node: Node<E>) { //since we have a new class RBNode this doesn't work
TODO()
}
override fun removeNode(): Node<E> { //same problem
TODO()
}
inner class RBNode<E>(data: E, var color: NodeColor, var parent: RBNode<E>?, left: RBNode<E>? = null, right: RBNode<E>? = null) : Node<E>(data, left, right){
fun switchColor() : NodeColor{
color = when (color) {
NodeColor.RED -> NodeColor.BLACK
else -> NodeColor.RED
}
return color
}
}
}
enum class NodeColor {
RED,
BLACK
}
abstract class BinaryTree<E : Comparable<E>>() {
abstract val rootNode: Node<E>
abstract fun addNode(node : Node<E>)
abstract fun removeNode() : Node<E>
abstract inner class Node<E : Comparable<E>>(
private val data: E,
private val left: Node<E>? = null,
private val right: Node<E>? = null) : Comparable<Node<E>> {
fun isLeaf(): Boolean{
return (left == null && right == null)
}
override fun compareTo(other: Node<E>): Int {
return data.compareTo(other.data)
}
}
}
这并不是 Java 或 Kotlin 的真正限制。这个案例即使在概念上也很棘手。让我们思考一下吧。
我们有一个共同的对象“家族”。然后我们有一个更专业的家庭,只接受与自己的家人一起工作。
RBTree
不接受仅使用任何 Node
,它特别需要 RBNode
,例如在 addNode()
中。这意味着 RBTree
实际上 不是 BinaryTree
的子类型,因为它不能用作
BinaryTree
。有多种方法可以解决这个问题,具体取决于我们的具体情况。
如果我们最初构建整个图,然后只使用它,但不再改变它,那么我们可以分离只读和可变接口。只有构建图表的初始代码必须确保
RBTree
正确获得
RBNode
。然后
RBTree
可以安全地视为只读
BinaryTree
,并且根据我们是否使用
RBTree
或
BinaryTree
,我们将节点视为
RBNode
或
Node
。针对某些情况的另一种方法是将
Node
调整为
RBNode
。在此解决方案中,
RBTree
允许向其中添加常规
Node
对象,但它将它们包装在自己的类中,并且当返回时,它返回包装的
RBNode
。这种方法还允许
RBTree
成为
BinaryTree
的子类型。第三种解决方案是通过节点类型参数化树。我们必须在代码周围的多个地方引入
N: Node<N, E>
:
class RBTree<E : Comparable<E>> : BinaryTree<RBTree.RBNode<E>, E>(){
override val rootNode: RBNode<E>
get() = TODO("Not yet implemented")
override fun removeNode(): RBNode<E> {
TODO("Not yet implemented")
}
override fun addNode(node: RBNode<E>) {
TODO("Not yet implemented")
}
class RBNode<E : Comparable<E>>(data: E, var color: NodeColor, var parent: RBNode<E>?, left: RBNode<E>? = null, right: RBNode<E>? = null)
: Node<RBNode<E>, E>(data, left, right){
fun switchColor() : NodeColor{
color = when (color) {
NodeColor.RED -> NodeColor.BLACK
else -> NodeColor.RED
}
return color
}
}
}
abstract class BinaryTree<N: BinaryTree.Node<N, E>, E : Comparable<E>>() {
abstract val rootNode: N
abstract fun addNode(node : N)
abstract fun removeNode() : N
abstract class Node<N: Node<N, E>, E : Comparable<E>>(
private val data: E,
private val left: N? = null,
private val right: N? = null) : Comparable<N> {
fun isLeaf(): Boolean{
return (left == null && right == null)
}
override fun compareTo(other: N): Int {
return data.compareTo(other.data)
}
}
}
这样我们就可以确保 RBTree
仅适用于
RBNode
。请注意,
RBTree
不再是
BinaryTree<Node>
的子类型。相反,它是
BinaryTree<RBNode>
的子类型。