简体   繁体   English

在 Kotlin 数据类中调用超类构造函数之前的访问函数

[英]Access function before calling superclass constructor in Kotlin data class

I'm using data classes in Kotlin to significantly reduce the amount of Java code I would otherwise have to write.我在 Kotlin 中使用数据类来显着减少我必须编写的 Java 代码量。

However, in one of my Java classes, I'm not sure what to do to achieve the same result in Kotlin.但是,在我的一个 Java 类中,我不确定如何在 Kotlin 中实现相同的结果。

My Java class looks a bit like this:我的 Java 类看起来有点像这样:

public class DataObject {

    private int mId;
    private String mName;

    public DataObject(int id, String name) {
        mId = id;
        mName = name;
    }

    public DataObject(Context context, int id) {
        mId = id;
        Cursor cursor = ...
        cursor.moveToFirst();
        mName = cursor.getString(...);
        cursor.close();
    }

    public int getId() {
        return mId;
    }

    public String getName() {
        return mName;
    }

}

I've tried to rewrite it in Kotlin, and so far I have this:我试图用 Kotlin 重写它,到目前为止我有这个:

data class DataObject(val id: Int, val name: String) {

    constructor(context: Context, id: Int) : this(id, fetchName(context))

    private fun fetchName(context: Context): String {
        val cursor = ...
        cursor.moveToFirst()
        val name = cursor.getString(...)
        cursor.close()
        return name
    }

}

But my IDE (Android Studio) is underlining the part where I call fetchName(context) in my constructor in red.但是我的 IDE (Android Studio fetchName(context)在我的constructor fetchName(context)红色强调了我调用fetchName(context)的部分。 It displays the following message:它显示以下消息:

Cannot access fetchName before superclass constructor has been called在调用超类构造函数之前无法访问fetchName

How should I resolve this issue?我应该如何解决这个问题?

You can only use member functions on a fully constructed objects.您只能在完全构造的对象上使用成员函数。 One way to work around that is to use private extension function or simply a function to fetch name:解决这个问题的一种方法是使用私有扩展函数或简单的函数来获取名称:

private fun Context.fetchName(): String {
    ///...
    return cursor.getString(1)
}

data class DataObject(val id: Int, val name: String) {
    constructor(context: Context, id: Int) : this(id, context.fetchName())
}

Although I do think that using Cursor is a bit too heavy job for constructor .虽然我确实认为使用Cursorconstructor有点太繁重了。 I'd use separate Factory like so:我会像这样使用单独的Factory

data class DataObject(val id: Int, val name: String) {
    object FromCursorFactory {
        fun create(id: Int, context: Context): DataObject {
            val name = context.fetchName()
            return DataObject(id, name)
        }
    }
}

Further reading:进一步阅读:

Another approach is to use companion object.另一种方法是使用伴随对象。 This will allow you to call the function outside of the data class as well (maybe not useful in your particular case)这也将允许您在数据类之外调用该函数(在您的特定情况下可能没有用)

data class DataObject(val id: Int, val name: String) {

  constructor(context: Context, id: Int) : this(id, fetchName(context))

  companion object {

    fun fetchName(context: Context): String {
      val cursor = ...
      ...
      return name
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM