I'm using data classes in Kotlin to significantly reduce the amount of Java code I would otherwise have to write.
However, in one of my Java classes, I'm not sure what to do to achieve the same result in Kotlin.
My Java class looks a bit like this:
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:
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. It displays the following message:
Cannot access
fetchName
before superclass constructor has been called
How should I resolve this issue?
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
}
}
}
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
. I'd use separate Factory
like so:
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With