What is the difference between a normal class and a data class in Kotlin?
I tried to resolve task #6 (DataClass) at Kotlin Koans. When I used the normal class in code, the test case failed.
Here's my code of the data class:
data class Person(val name: String, val age: Int)
fun task6(): List<Person> {
return listOf(Person("Alice", 29), Person("Bob", 31))
}
Here's result of the data class:
[Person(name=Alice, age=29), Person(name=Bob, age=31)]
Here's my code of the normal class:
class Person(val name: String, val age: Int)
fun task6(): List<Person> {
return listOf(Person("Alice", 29), Person("Bob", 31))
}
Here's result of the normal class:
[i_introduction._6_Data_Classes.Person@4f47d241, i_introduction._6_Data_Classes.Person@4c3e4790]
Does that mean there is difference between a normal class and a data class in Kotlin. If yes, what is that?
Updated:
Thank @Mallow, you are right. That works:
class Person(val name: String, val age: Int) {
override fun toString(): String {
return "Person(name=$name, age=$age)"
}
}
fun task6(): List<Person> {
return listOf(Person("Alice", 29), Person("Bob", 31))
}
Most of the time we developers use class to keep only data in classes. Classes have some methods which needs to be overwritten wrt the data it holds. ex: hashCode()
, equals()
.
Data classes automatically take care of such utilities.
From the official documentation:
We frequently create a class to do nothing but hold data. In such a class some standard functionality is often mechanically derivable from the data. In Kotlin, this is called a data class and is marked as
data
.
The compiler automatically derives the following members from all properties declared in the primary constructor:
- equals()/hashCode() pair,
- toString() of the form "User(name=John, age=42)",
- componentN() functions corresponding to the properties in their order of declaration,
- copy() function (see below). If any of these functions is explicitly defined in the class body or inherited from the base types, it will not be generated.
To read more, check data-classes
About the result, Technically, you are getting is different because of implementation of toString()
method. data class' toString()
method uses data class properties and values to form returning string. General class' toString()
method uses hash code to form returning string.
for a data class.
The compiler automatically derives the following members from all properties declared in the primary constructor:
equals()/hashCode() pair,
toString() of the form "User(name=John, age=42)",
componentN() functions corresponding to the properties in their order of declaration,
copy() function (see below).
see https://kotlinlang.org/docs/reference/data-classes.html
A class
represents some data "type" and its behaviour(s) so from that point of view data class
isn't any different than a class
. But there are certain behaviours and rules about a data class
that makes it a bit different:
- Calling
toString()
on a data class dumps a string with all its member properties. - It has
componentN
method thatget
member properties by their ordern
. - It has a
copy
method which takes the member properties as parameters for making a diff copy of the object. - A
data class
can not be open. Cant be inherited. - It can not be
abstract
. - It can not be
nested
,inner
orsealed
. - Although it can inherit, define abstract methods and implement interfaces.
-
data class
properties can be destructed into individual variables e.gval (name, address) = Person("name", "address")
-
Pair(a, b)
internally usesdata class
.