You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin/Java中如何在子类重写抽象类的抽象内部类

问题描述

我定义了代表二叉树的抽象类BinaryTree,希望创建其子类RBTree,复用BinaryTree的所有抽象能力,同时修改内部的Node抽象类,使其具备颜色(color)和父节点(parent)属性。但不清楚Kotlin或Java是否支持该操作及实现方式。目前仅能创建Node的子类RBNode,但这会破坏BinaryTree的抽象设计,因需使用不同Node对象;直接重定义Node类也无效。

可行解决方案(Kotlin)

核心思路是让BinaryTree通过泛型约束关联自定义的Node类型,这样子类可以指定自己的Node实现,同时复用父类的抽象能力。

1. 修改抽象父类BinaryTree

将BinaryTree改为带双泛型的抽象类,其中第二个泛型约束为自身的Node类型,确保子类可以传入自己的Node实现:

abstract class BinaryTree<E : Comparable<E>, N : BinaryTree.Node<E, N>>() {

    abstract val rootNode: N

    abstract fun addNode(node: N)

    abstract fun removeNode(): N

    abstract inner class Node<E : Comparable<E>, N : Node<E, N>>(
        protected val data: E,
        protected val left: N? = null,
        protected 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)
        }
    }
}

关键修改点:

  • 新增泛型N,约束为BinaryTree.Node<E, N>,强制Node的子类必须符合该类型
  • 将rootNode、addNode、removeNode的类型从Node<E>改为N
  • 将Node类的data、left、right的访问修饰符从private改为protected,让子类RBNode可以访问

2. 实现RBTree子类

现在RBTree可以指定泛型N为自己的RBNode,完美复用父类的抽象能力,同时拥有自定义的Node属性:

class RBTree<E : Comparable<E>> : BinaryTree<E, RBTree.RBNode<E>>() {

    override val rootNode: RBNode<E> = TODO("初始化根节点")

    override fun addNode(node: RBNode<E>) {
        TODO("实现红黑树的添加逻辑")
    }

    override fun removeNode(): RBNode<E> {
        TODO("实现红黑树的删除逻辑")
    }

    inner class RBNode<E : Comparable<E>>(
        data: E,
        var color: NodeColor,
        var parent: RBNode<E>?,
        left: RBNode<E>? = null,
        right: RBNode<E>? = null
    ) : BinaryTree.Node<E, RBNode<E>>(data, left, right) {

        fun switchColor(): NodeColor {
            color = when (color) {
                NodeColor.RED -> NodeColor.BLACK
                else -> NodeColor.RED
            }
            return color
        }
    }
}

enum class NodeColor {
    RED,
    BLACK
}

说明:

  • RBTree继承BinaryTree<E, RBNode<E>>,明确指定使用自己的RBNode作为Node类型
  • RBNode继承BinaryTree.Node<E, RBNode<E>>,自动继承父类Node的所有方法,同时扩展了color、parent属性和switchColor方法
  • 父类的addNode、removeNode现在直接接收/返回RBNode<E>,不需要类型转换,也不会破坏抽象设计

为什么这个方案可行?

通过泛型约束,我们让BinaryTree的抽象能力与具体的Node实现解耦,既保留了父类的通用二叉树抽象,又允许子类自定义Node的扩展属性和方法,完美解决了“复用抽象”和“自定义Node”的矛盾。

Java版本实现思路(补充)

Java的实现逻辑和Kotlin一致,同样通过泛型约束实现:

  1. 将BinaryTree定义为abstract class BinaryTree<E extends Comparable<E>, N extends BinaryTree.Node<E, N>>
  2. 内部Node类改为abstract static class Node<E extends Comparable<E>, N extends Node<E, N>>(Java内部类需用static避免持有外部类引用)
  3. RBTree继承BinaryTree<E, RBTree.RBNode<E>>,RBNode继承BinaryTree.Node<E, RBTree.RBNode<E>>

内容的提问来源于stack exchange,提问作者Luke Abruzese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:44:53