Почему объект не может ссылаться на родительский объект и дочерний объект?

#kotlin #object #oop #nodes

Вопрос:

Послушайте, я столкнулся с этой основной проблемой, когда я хочу создать своего рода узлы, где узел является категорией, и у него может быть родительская категория и список ее дочерних категорий, я только что понял, что это невозможно в ООП, или я ошибаюсь? Я могу справиться со своим случаем таким образом, что у каждого объекта будет только список его потомков, но тогда мне придется (по моему мнению) излишне фильтровать все категории, чтобы найти его родителя. Вот основная идея проблемы, с которой я сталкиваюсь

введите описание изображения здесь

Почему это происходит?

Ответ №1:

Все ваши конструкторы требуют, чтобы были построены родитель и потомок, прежде чем можно будет построить текущий объект. В вашем случае это невозможно, поскольку ссылки образуют цикл зависимостей ( First -> > Fourth -> > Third -> > Second -> > First , поэтому First не может быть полностью создано до тех пор, пока First не будет создано, и т. Д.).

Одним из решений было бы сделать Node абстракцию (или интерфейс) и извлекать значения только тогда, когда они запрашиваются (т. е. в геттерах):

 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 обычно не создаются до их первого использования.

  1. Первый объект , который вы используете (в main ), — это First , поэтому вызывается его конструктор.
  2. Первое, что делает его конструктор, — это получает ссылку на Fourth , что , в свою очередь , делает Third , что, в свою очередь, делает Second , что, в свою очередь, пытается сделать First , но First уже находится в процессе создания, поэтому его ссылка есть null .
  3. Затем (мы все еще в Second ) он пытается создать Third (как child ), который находится в процессе создания, поэтому его ссылка также null есть . На этом точка Second сделана, поэтому никаких дальнейших ссылок на нее не будет null .
  4. Third теперь имеет действительную ссылку Second и переходит к попытке создания Fourth , которая все еще создается, таким образом null . Теперь Third все кончено.
  5. Fourth теперь имеет действительную ссылку Third и переходит к First тому , что все еще создается, таким образом null . Теперь Forth все кончено.
  6. First теперь имеет действительную ссылку Fourth и переходит к Second тому , что уже существует и является действительным. Теперь First все кончено.

*Технически второе, поскольку первое, что он делает, — это устанавливает номер, но это первое, что имеет значение для целей этого обсуждения.