DataClasses in Kotlin - Overriding the equals() from 'Any' Class

82 Views Asked by At

I've been working on overriding the equals() from Any class. But in the below code. I'm confused why "if (other is Person)" is necessary to get the "if(this.firstName == other.firstName)" statement to work.

fun main()
{
 var personObj1 = Person("Adam","S")
 var personObj2 = Person("Adam","S")
 println(personObj1.equals(personObj2))

}

class Person(var firstName:String, var lastName:String)
{

    override fun equals(other: Any?): Boolean {
       if (other is Person) {
            if (this.firstName == other.firstName) {
                return true
            }
        }
        return  false
    }

}

Without the if(other is Person) statement, code gives the below error

enter image description here

1

There are 1 best solutions below

0
On

Short Answer:

other is of type Any?, the check for other is Person smartcasts it to Person, which makes the firstName property available.

Long Answer: A few things to note about this question and the code:

  1. The title and the tags mention "data class". If you were to actually use data class, equals and hashCode are generated automatically and you don't have to implement them. Check the documentation about data classes to find out whether they are applicable in your situation (they probably are).
  2. Always override hashCode() IF you manually override equals() and vice versa. Not doing so can lead to serious performance problems or even bugs when using hash-based data structures like HashMap or HashSet. Again, if you're using data class, no need to worry about this.
  3. As a rule of thumb in Kotlin, always use val instead of var up to the point where it doesn't work anymore (because you have to reassign it). Using var can disable smart casts in a lot of situations and therefore make your code less elegant. In your example, all occurrences of var can most likely be swapped out for val.
  4. Just as you're using the == operator to check whether this.firstName is equal to other.firstName, you can (and should) use == to compare personObj1 and personObj2 in your main function. See operator overloading.
  5. You should always simplify statements in the form of
if (something) {
    return true
} else {
    return false
}

to just

return something

In your snippet, there's no else branch, but still the implementation could be simplified to

override fun equals(other: Any?) = (other is Person) && (firstName == other.firstName)

(see also: expression functions)

  1. Make sure to follow the official Kotlin coding conventions as your style guide for formatting and the like, in order to ensure readability. IntelliJ already has this style guide integrated and can automatically format all source files for you.