#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 обычно не создаются до их первого использования.
- Первый объект , который вы используете (в
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
все кончено.
*Технически второе, поскольку первое, что он делает, — это устанавливает номер, но это первое, что имеет значение для целей этого обсуждения.