如何在其子类(kotlin 或 java)中重写抽象类的抽象内部类

问题描述 投票:0回答:1

所以基本上我有一个代表下面的二叉树的抽象类。我想创建一个名为 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 subclass abstract inner-classes
1个回答
0
投票

这并不是 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>
 的子类型。

© www.soinside.com 2019 - 2024. All rights reserved.