Android котлин - вторичный конструктор - PullRequest
0 голосов
/ 01 сентября 2018

Я хочу реализовать класс с двумя constrcutors. И пустой конструктор и еще один с параметром user:FirebaseUser

Но я получаю сообщение об ошибке:

"В изменении делегирования есть цикл"

class UserModel(user: FirebaseUser) {

    var uid: String?
    val email: String?
    val phoneNumber: String?
    val photoUrl: String
    val displayName: String?

    //error message: There is a cycle in the delegation change
    constructor():this() {}


    init {
        this.displayName = user.displayName
        this.email = user.email
        this.phoneNumber = user.phoneNumber
        this.photoUrl = user.photoUrl!!.toString()
        this.uid = user.uid
    }



    companion object {

        @Exclude
        val CURRENT_LOCATION = "location"
    }

}

Я пробовал несколько подходов без успеха. Любая помощь?

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Все вторичные конструкторы должны вызывать первичный конструктор, прямо или косвенно. Что означает:

class X(var x: Int){
    constructor() : this(0.0);
    constructor(x: Double) : this(x.toInt());
}

Однако вы не можете сделать это:

class X(var x: Int){
    constructor() : this();
    constructor(x: Double) : this();
}

Потому что это приведет к исключению переполнения стека.

Приведенный выше пример - ужасный код, но это просто демонстрация.

Так с этой строкой:

constructor():this() {}

Вы заставляете вторичный конструктор вызывать себя.

Вместо этого вызовите основной конструктор. Это означает, что вам нужно передать FirebaseUser в качестве аргумента. Я не знаком с Firebase, поэтому я оставлю это вам.

Но в качестве примера, вы, в основном, должны сделать это вместо этого:

constructor() : this(FirebaseUser());

Либо инициализируйте напрямую, либо получите его из метода. Если вы не можете получить его, вы, конечно, можете просто сделать его обнуляемым.

Но если вы имеете дело с обнуляемыми значениями, предполагая, что большая часть вашего кода находится в Kotlin, вы можете просто сделать его обнуляемым со значением по умолчанию и удалить вторичный конструктор:

class UserModel(user: FirebaseUser? = null){
    init{
        // Now that `user` is nullable, you need to change the assignments to include null-safe or non-null assertion (?. or !!. respectively)
    }
}
0 голосов
/ 01 сентября 2018

Вы должны вызывать первичный конструктор из каждого имеющегося у вас вторичного конструктора, поскольку его параметры могут использоваться в инициализаторах свойств и блоках инициализатора, как вы использовали user в блоке init в своем коде.

С этим кодом вторичный конструктор просто рекурсивно вызывает себя:

constructor() : this() {}

Вместо этого вы должны вызвать первичный конструктор, чтобы можно было инициализировать свойства класса:

constructor() : this(FirebaseUser()) {} // get FirebaseUser from somewhere

В качестве альтернативы, если то, что вы хотели сделать, это оставить все null при вызове вторичного конструктора без параметров, вы можете выбрать что-то вроде этого:

class UserModel(user: FirebaseUser?) {

    var uid: String? = user?.uid
    val email: String? = user?.email
    val phoneNumber: String? = user?.phoneNumber
    val photoUrl: String? = user?.photoUrl?.toString()
    val displayName: String? = user?.displayName

    constructor() : this(null)

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...