Android data class trick and tips for developers

Here we will read how to solve some problems which developer faces in the day to day life with Kotlin data classes, But before it If you have no idea about Kotlin data class then first read about it in short way.

What is Kotlin Data class

Data classes specialize in holding data. The Kotlin compiler automatically generates the following functionality for them:

A correct, complete, and readable toString() method

Value equality-based equals() and hashCode() methods

Utility copy() and componentN() methods

To appreciate the amount of functionality a data class provides automatically, compare the following equivalent code snippets. For more about data class, Click here.

Creating Kotlin Data Class

Following are the requirements for creating Kotlin Data class.

  • You need to append the class with the keyword data
  • The primary constructor needs to have at least one parameter.
  • Each parameter of the primary constructor must have a val or a var assigned. This isn’t the case with a normal class, where specifying a val or a var isn’t compulsory.
  • Data classes cannot be appended with abstract, open, sealed or inner

Kotlin Data Class built-in methods

Kotlin Data class automatically creates the following functions for you.

  • equals() and hashCode()
  • toString() of the form "Book(name=JournalDev, authorName=Anupam)"
  • componentN() functions for each of the parameters in the order specified. This is known as destructuring declarations.
  • copy()

Kotlin Data Class Features

Following are some features that a Data Class provides.

  • To create a parameterless constructor, specify default values to each of the parameters present in the primary constructor.
  • A Data Class allows subclassing(No need to mention the keyword open).
  • You can provide explicit implementations for the functions equals() hashCode() and toString()
  • Explicit implementations for copy() and componentN() functions are not allowed.
  • We can control the visibility of the getters and setters by specifying the visibility modifiers in the constructor as shown below.

data class Book(var name: String,private var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)

  • A val parameter won’t have a setter defined implicitly(can’t be done explicitly too!).

In detail for Kotlin data class, You can read from here.

Now let’s start in depth of Kotlin Data classes. Here we will try to fix some problems which comes in day to day life of Android Developer.

So here we will discuss some below points to fix through Kotlin data classes:-

  1. How to read override data variable value if variable is Constant.
  2. How to over write data variable value if variable is Constant.
  3. How to extends one data class to another data class.
  4. How to create multiple constructor with data class.

1. How to read override data variable value

If There is a data class which has variable name like firstName and it’s val it means Constant.

data class KotlinDataClasses(val firstName:String)

Now if i will set value in first Name as “Abhi” but when we will read it then it should be “Mr. Abhi”. How we can achieve it. Because first Name is constant so how we can modify it.

So now we will create a new variable and assign existing firstName value to it and use their get() method to update code as we per need.

data class KotlinDataClasses(val firstName:String){var firstNameNew = firstName
get() = "Mr. "+ field
}

Now we have to read new variable firstName_ rather than firstName.

val dataClass=KotlinDataClasses(firstName = "Abhi")
Log.e("Updated value",dataClass.firstName_)

When we run the program then we will see the output is now “Mr. Abhi” rather than “Abhi”.

E/Updated value: Mr. Abhi

So using this changes inside kotlin data classes, We can achieve it. If any other type logic you want to add you can do it. Check here for more.

2. How to over write data variable value

Here we can’t override firstName as it’s constant so Now we will use same data class as we used above and let’s try with different approach. Like if existing firstName is “Abhi” but we need first name “Abhi” Or want to change it into “Abhishek” later or need both without change data class signature. So how we can achieve it using two approch.

A-First discuss about first approch. If we want to only modify variable value later then we can achieve it to change firstName from val to var.

data class KotlinDataClasses(var firstName:String)

and can update value later but now only updated value will be exist .

val dataClass=KotlinDataClasses(firstName = "Abhi")
Log.e("dataClass.firstName->",dataClass.firstName)
dataClass.firstName= "Abhishek"
Log.e("dataClass.firstName->",dataClass.firstName)

Here you will see that it will not getting any compile time error when modifying value of firstName. And when we run the program.

2022-10-29 22:56:17.159 18212-18212/com.demo.dynamicuiwithcomposeui E/dataClass.firstName->: Abhi
2022-10-29 22:56:17.159 18212-18212/com.demo.dynamicuiwithcomposeui E/dataClass.firstName->: Abhishek

Here we will see now firstName is changed from “Abhi” to “Abhishek”.

B- Now discuss about Second Approach. Here we will use point 1 approach and use set() method to change value of firstName_ .

data class KotlinDataClasses(val firstName:String){

var firstName_ = firstName
get() = field
set(value) {
field = value
}
}

Now let’s see, Here we have set firstName to “Abhi”

val dataClass=KotlinDataClasses(firstName = "Abhi")
Log.e("dataClass.firstName->",dataClass.firstName)
Log.e("dataClass.firstName_P->",dataClass.firstName_)

and will see output for both variable.

E/dataClass.firstName->: Abhi
E/dataClass.firstName_P->: Abhi

Right now both output are same, But here we can modify to firstName_ and can set value to “Abhishek” .

val dataClass=KotlinDataClasses(firstName = "Abhi")
Log.e("dataClass.firstName->",dataClass.firstName)
Log.e("dataClass.firstName_P->",dataClass.firstName_)
dataClass.firstName_="Abhishek"
Log.e("dataClass.firstName_N->",dataClass.firstName_)

Let’s run the program and see the output now.

2022-10-29 22:43:20.507 12817-12817/com.demo.dynamicuiwithcomposeui E/dataClass.firstName->: Abhi
2022-10-29 22:43:20.507 12817-12817/com.demo.dynamicuiwithcomposeui E/dataClass.firstName_P->: Abhi
2022-10-29 22:43:20.507 12817-12817/com.demo.dynamicuiwithcomposeui E/dataClass.firstName->: Abhi
2022-10-29 22:43:20.507 12817-12817/com.demo.dynamicuiwithcomposeui E/dataClass.firstName_N->: Abhishek

If you see the output, you will find that we can get both firstName having “Abhi” and firstName_ now having “Abhishek”. So its possible using above approch.

3. How to extends one data class to another data class

The truth is: data classes do not play too well with inheritance. We are considering prohibiting or severely restricting inheritance of data classes. For example, it’s known that there’s no way to implement equals() correctly in a hierarchy on non-abstract classes. Data class contains some generated methods, like hashCode, equals, copy,… You could break those methods in class extending data class, but kotlin needs to guarantee that they work properly. That’s the reason for making data class impossible to extend.

So sure you can’t use inheritance with data class. Then the question if i want to do it any how then how i can do it.

So the answer is, You can achieve this feature but in different ways like.

  1. With the help of interface

Here first create a interface and add variable which you want to inherit on other data classes where you want to use.

interface Human {
val name: String
}

data class Woman(override val name: String) : Human

data class Mom(override val name: String, val numberOfChildren: Int) : Human

2. With the help of Sealed Class

Here first create a Sealed class and add variable which you want to inherit on other data classes where you want to use.

sealed class Human {
abstract val name: String
}

data class Woman(override val name: String) : Human()

data class Mom(override val name: String, val numberOfChildren: Int) : Human()

3. With the help of Abstract Class

Here we will follow the same approch as follwed on above but only difference is that make the property open and override it in the data class primary constructor declaration.

abstract class Base(open val data1: String)

abstract class Token(open var index: Int = 0)

data class CloseLoop(
override var index: Int,
var openLoopIndex: Int = 0
) : Token(index)
Or Declare a property with another name and initialize the base class with it:data class CloseLoop(val theIndex: Int, var openLoopIndex: Int = 0) : Token(theIndex)

4. How to create multiple constructor with data class to use with two different case

data class TestDataClass(val name: String){
constructor(name: String, age: Int) : this(name)
}

And you can use this data class to handle both use case like below.
TestDataClass("Abhishek") Or
TestDataClass("Abhishek",30)
And above both test case will work without any type of error.

The full detail about it, You can click here.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Abhishek Srivastava

Abhishek Srivastava

165 Followers

Senior Software Engineer | Android | Java | Kotlin |Xamarin Native Android |Flutter |Go