Why can't object refer to parent object and child object?

Viewed 160

Look, I'm facing this basic problem where I want to construct sort of nodes where node is a category and it could have parent category and list of it's children categories, I just realized that it's impossible in OOP or am I wrong? I can handle my case in a way that each object will have only list of its children but then I'll have to (in my opinion) unnecessarily filter through all of the categories to find it's parent here is a basic idea of problem I'm facing

enter image description here

Why is this happening?

1 Answers

All your constructors require the parent and child to be constructed before the current object can be constructed. That is impossible in your case as the references form a dependency cycle (First -> Fourth -> Third -> Second -> First, therefore First can't be fully created till after First is created, etc.).

One solution would be to make the Node abstract (or an interface) and only fetch the values when they are requested (i.e. in the getters):

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

If you're interested in why you got that particular pattern of nulls, it's important to remember that objects in Kotlin usually aren't created till the first time they are used.

  1. The first object you use (in main) is First, so it's constructor is called.
  2. The first* thing its constructor does is get a reference to Fourth, which in turn does Third, which in turn does Second, which in turn tries to do First, but First is already in the process of being created, so its reference is null.
  3. Then (we're still in Second) it tries to create Third (as the child), which is in the process of being created, so its reference is also null. At this point Second is done, so any future reference to it will not be null.
  4. Third now has a valid reference to Second, and moves on to trying to create Fourth, which is still being created, thus null. Now Third is done.
  5. Fourth now has a valid reference to Third, and moves on to First, which is still being created, thus null. Now Forth is done.
  6. First now has a valid reference to Fourth, and moves on to Second, which already exists and is valid. Now First is done.

*Technically the second, since the first thing it does is set the number, but it's the first thing that matters for the purposes of this discussion.

Related