Search code examples
kotlinclassdata-classdefault-implementation

android - kotlin differences between Normal class and data Class of methods default implementations


I read about differences between class and dataclass in kotlin from this

https://medium.com/@dubemezeagwu/difference-between-normal-classes-data-classes-in-kotlin-a01f636e8900

i need someone explain the second point by example, when i tried it as i understood i failed , the third point say that:

Data classes have default implementations for the following methods using only properties that were declared in the primary constructor; toString(), hashCode(), copy(), componentN(), equals(). Implementation for those methods can be written in normal classes using properties that were and were not declared in the primary constructor.


Solution

  • I think you are referring to second point. Let me explain in simpler terms.

    Each class extends from Object class in java and in kotlin similar thing is Any These root class only have the methods like toString(), hashCode(), copy(), equals()... These have default implementation in root. For example: You have a class IFoo. (Internally it extends Any class)

    class IFoo(val k:String,val h: String)
    
    val a = Ifoo("Hi,","Hello")
    println(a.toString())
    

    //It will print like below. {Classname@{HashcodeOfObject}}

    enter image description here

    This is the default toString() implementation of Object and Any class.If you need to print your own values you need to override toString() method in Ifoo.

    class IFoo(val k:String,val h: String){
        override fun toString(): String {
            return "Overridden : $k - $h"
        }
    }
    
    val iFoo = IFoo("Hi","Hello")
    println("$iFoo")
    

    It will provide below output for toString() . As we have overridden default implementation and provided our own implementation.

    enter image description here

    Then coming to data class.

    data class Foo(val a:String)
    
        val foo = Foo("abc","--hello")
        println("$foo")
    

    enter image description here

    When we print data class directly it provides its own default implementation and prints all variables that are passed into the constructor.

    You cannot create data class without default arguments . Data class must have atleast one argument in constructor. So it will print the value of argument. Similarly data class have its own implementation of other functions. But for normal class ,we can create object from empty constructor.

    So only while inheriting data class from another data class it cant handle which toString() method to implement. So only decision made by Kotlin team not to support inheritance in data class. So data class are made as final class . So no other class can inherit it.

    Here DC - Data Class , NC - Normal Class , : - Inheritance

    data class Foo(val a:String,val b:String) //DC
    
    open class IFoo(val k:String,val h: String) //NC
    
    data class Bar(val b:Int,val c:String): Foo(b,c) // DC:DC - Not Possible
    
    data class Bar(val b:Int,val c:String): IFoo(b,c) // Possible DC : NC - Possible
    
    class IBar(val x:String,val y:String):Foo(x,y) // NC : DC - Not possible
    
    class IBar(val x:String,val y:String):IFoo(x,y) // NC:NC - Possible
    

    Hope it helps!!