Android Kotlin-二级构造函数

时间:2018-09-01 13:37:57

标签: android kotlin

我想实现一个具有两个构造函数的类。空的构造函数和另一个带有参数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 :(得分:2)

所有辅助构造函数都必须直接或间接调用主构造函数。意思是:

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)
    }
}

答案 1 :(得分:1)

您必须从拥有的每个辅助构造函数中调用主构造函数,因为它的参数可能在属性初始化程序和初始化程序块中使用,就像您在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)

}