Android Kotlin

Kotlin data class inheritance

Kotlin data class

A compiler-derived Kotlin data class that holds data (of an object) is the Kotlin Data Class. The data keyword is used to define a Kotlin Data Class. Let’s assume we have to use the Student class that has name, email, and age. The only thing we have to do is write the definition as follows.

data class Student(val name: String,val email: String, val age: Int)

Kotlin compiler can generate the entire class. Kotlin compiler will automatically generate the entire class.

Kotlin data classes: Why should we use them?

Before we move on to the practical code examples, let’s briefly talk about the benefits of Kotlin Data Class. There are many reasons to use this feature exclusively on Kotlin.

  • This makes it much easier to write boilerplate model classes.
  • RecyclerView/Diffutil can be used efficiently.
  • Unit testing is made much simpler.
  • To generate codes, you don’t need libraries like Lombok
  • Data classes can be used in conjunction with architectural patterns like MVVM or MVP.

It is necessary to define variables, create getter- and setter methods, and create constructors. Also, we need to use toString, hashcode and equals to override them.

Also Read: Kotlin tutorial for Android 

Java Data Class example

This is what it would look like if we had created a data type named “student” using java. It would have had a name and email, as well as age.

Kotlin Data Class Example

It would have been super concise if we had used Kotlin to create the code above.

data class Student(val name: String,val email: String, val age: Int)

Compiler-Generated Functions ( Kotlin data class )

  • Copy
  • ToString
  • Equals
  • hashCode
  • componentN

These functions will be discussed in greater detail in the final sections of this tutorial.

How to use Kotlin Data Classes?

This is how you can instantiate a Kotlin Data Class.

val student1 = Student("Jane","jane@gmail.com",27)

Let’s create a second student object (instantiate).

val student2 = Student("Alex","alex@gmail.com",35)

All of the properties are available once you have instantiated classes as we did. Let’s create another variable and assign the summation of the ages to two students. val sumOfAges = student1.age + students2.age

curly brackets are required after the dollar sign to indicate that we are using a property within a String. Like this $student1.name

This is how to write a Toast message that shows the names and sum of ages. This will show you how to use the properties of a Kotlin Data item.

Toast.makeText( this,
        "Welcome ${student1.name} and ${student2.name} , sum of ages is $sumOfAges",
            Toast.LENGTH_LONG
        ).show()

 

sumOfAges can be described as a variable. It is a variable. I used it with the ($). dollar sign. Curly brackets were necessary to extract the names of the objects’ values.

Let me give you another example. Here’s how you can use them to make a log.

Log.i("MyTAG","Age of ${student1.name} is ${student1.age}")
Log.i("MyTAG","Email of ${student2.name} is ${student2.email}")

This is the main activity code. I created a data class called Student. Then I used it to create (instantiate), two Student objects. I created a Toast message for students to welcome them. I also wrote codes to log their values.

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        data class Student(val name: String, val email: String, val age: Int)
        val student1 = Student("Parmit", "parmit@gmail.com", 29)
        val student2 = Student("Malik", "codeplayon@gmail.com", 35)
        val sumOfAges = student1.age + student2.age
        Toast.makeText(
            this,
            "Welcome ${student1.name} and ${student2.name} , sum of ages is $sumOfAges",
            Toast.LENGTH_LONG
        ).show()
        Log.i("MyTAG", "Age of ${student1.name} is ${student1.age}")
        Log.i("MyTAG", "Email of ${student2.name} is ${student2.email}")
    }
}

If you execute the above code you will see these log results on the Logcat tab.

I/MyTAG: Age of Parmit is 29
I/MyTAG: Email of Malik is codeplayon@gmail.com

Coping Data Objects

Kotlin lets us copy data objects. The most interesting thing about this is that it allows you to modify parts of an object while leaving the rest untouched.

I will copy student1 the object that we have created above, while also changing its age.

val student3 = Student1.copy (age = 23).

To see the results, let’s add a Log.

Log.i ("MyTAG", "Age copied $student3.name to $student3.age")

This is MainActivity as it appears now

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        data class Student(val name: String, val email: String, val age: Int)
        val student1 = Student("Parmit", "Parmit@gmail.com", 29)
        val student2 = Student("Malik", "codeplayon@gmail.com", 35)
        val sumOfAges = student1.age + student2.age

        Toast.makeText(
            this,
            "Welcome ${student1.name} and ${student2.name} , sum of ages is $sumOfAges",
            Toast.LENGTH_LONG
        ).show()

        Log.i("MyTAG", "Age of ${student1.name} is ${student1.age}")
        Log.i("MyTAG", "Email of ${student2.name} is ${student2.email}")
        val student3 = student1.copy(age = 25)
        Log.i("MyTAG", "Age of copied ${student3.name} is ${student3.age}")
    }
}

Now, if you run the app, you will see these Log results.

I/MyTAG: Age of Parmit is 29
I/MyTAG: Email of Malik is codeplayon@gmail.com
I/MyTAG: Age of copied Jane is 25

Data Objects that can be de-structurized

We have seen how Kotlin lets us create objects using properties (name, email, and age ). Kotlin allows us to do the reverse. Let me demonstrate how you can get properties back from objects. Kotlin can generate different componentN (N is the index) functions in order to obtain components individually.

ComponentN

Consider this Student data class that we created earlier.

data class Student(val name: String, val email: String, val age: Int)

This class has three properties. Kotlin will generate three-component functions for objects of this class. You can get Componet1 to give you the name, component2 to give you the email, and component3 to give you the age.

We have now created a student object. val student2 = Student (Malik”, “codeplayo@gmail.com”,35)

We can now de-structure it as follows.

student2.component1() // this will give the String name
student2.component2() // this will give the String email        
student2.component3() // this will give the Int age

Is it possible to code a class body?

A class body can be coded. These values can be used as well. Let me show you how to do this using a code example. I will be defining a Kotlin data type called Book, which has two properties in its primary constructor and one property within the. class body.

data class Book(val name: String, val pages: Int){
            val price = 34.5
        }
  val book = Book("MyStory",15)
  Log.i("MyTAG"," ${book.name} has ${book.pages} pages. It's price is ${book.price}" )

Here, the value that we have declared in the data class is literarily treated as a constant. However, generated functions like toString() will not be considered if the class body is ignored. Only properties that are declared in the class declaration (primary constructor) will be taken into consideration. You always have the option to override these functions.

 

ToString() Function

I will now log the result of the toString() function.

data class Book(val name: String, val pages: Int){
            val price = 34.5
        }
   val book = Book("Story",18)
   Log.i("MyTAG",book.toString())

Here is the log result.

I/MyTAG: Book(name=Story, pages=18)

Limitations to Kotlin Data Classes

The concept of Kotlin Data Class has many benefits. It also has a few minor limitations. These minor limitations are easily overlooked in most practical situations.

 

  • A data class can’t extend another data type.
  • ToString, equals, and hashCode cannot be overridden. It is not possible to override copy and componentN functions.
  • A data class must contain at least one parameter.
  • An inner, abstract, sealed, or open data class cannot be identified.