【发布时间】:2021-07-12 16:27:27
【问题描述】:
看,我正面临这个基本问题,我想构建一种节点,其中节点是一个类别,它可能有父类别和它的子类别列表,我刚刚意识到这在 OOP 中是不可能的,或者我错了?我可以通过一种方式处理我的案例,每个对象只有其子对象的列表,但是我将不得不(在我看来)不必要地过滤所有类别以找到它的父对象,这是我问题的基本概念米面
为什么会这样?
【问题讨论】:
看,我正面临这个基本问题,我想构建一种节点,其中节点是一个类别,它可能有父类别和它的子类别列表,我刚刚意识到这在 OOP 中是不可能的,或者我错了?我可以通过一种方式处理我的案例,每个对象只有其子对象的列表,但是我将不得不(在我看来)不必要地过滤所有类别以找到它的父对象,这是我问题的基本概念米面
为什么会这样?
【问题讨论】:
您的所有构造函数都需要先构造父对象和子对象,然后才能构造当前对象。在您的情况下这是不可能的,因为引用形成了一个依赖循环(First -> Fourth -> Third -> Second -> First,因此 First 直到之后才能完全创建First 已创建等)。
一种解决方案是使 Node 抽象(或接口)并仅在请求时(即在 getter 中)获取值:
interface Node {
val number: Int
val parent: Node?
val child: Node?
}
object First : Node {
override val number = 1
override val parent get() = Fourth
override val child get() = Second
}
// Similar for Second, Third, and Fourth
如果您对为什么会出现这种特定的空值模式感兴趣,请务必记住,Kotlin 中的对象通常要到第一次使用时才会创建。
main 中)是First,因此调用了它的构造函数。Fourth的引用,然后引用Third,然后再执行Second,然后尝试执行First,但First是已经在创建过程中,所以它的引用是null。Second)它尝试创建Third(作为child),它正在创建过程中,所以它的引用也是null。此时Second 已完成,因此以后对它的任何引用都不会是null。Third 现在有一个对Second 的有效引用,并继续尝试创建Fourth,它仍在创建中,因此null。现在Third 完成了。Fourth 现在有一个对Third 的有效引用,并转到First,它仍在创建中,因此是null。现在Forth 完成了。First 现在有一个对Fourth 的有效引用,然后转到已经存在且有效的Second。现在First 完成了。*技术上是第二个,因为它所做的第一件事是设置数字,但对于本次讨论而言,这是第一件事。
【讨论】: