10

I was trying to overload compareTo and equals operators for my class.

There is no problem with compare operator. It works well both as member and as an extension function.

The equals operator must be a member and override equals fun.

class MyClass { companion object { private val NUMBER: Int = 5 operator fun compareTo(value: Int) = NUMBER - value override operator fun equals(other: Any?) = when (other) { is Int -> NUMBER == other else -> throw Exception("") } } } fun test() { if (MyClass < 10) { //ok } //Operator '==' cannot be applied to 'MyClass.companion' and kotlin.Int if (MyClass == 5) { } } 

Edit: How to overload '==' properly?

1
  • I'm confused as to why you would want this. A correctly implemented equals method would always return false for a companion object except for when compared with itself (which is the default/inherited behavior). Commented Apr 7, 2016 at 19:37

2 Answers 2

4

Defining equals and hashCode is considered somewhat useless on object declarations that have no explicit supertype, according to this issue. Probably correct equals+hashCode implementations on objects have few use cases.

There's even an IDE inspection that shows a warning when you try to do so:

IDE warning screenshot
The warning is not there when the object has a declared supertype.

However, I don't think that some technical reason stops Kotlin from resolving the overloaded operator, and the whole behaviour is strange, so I filed an issue in Kotlin issue tracker.

As for now (Kotlin 1.0.2 EAP), even with declared supertype you can only check object's equality with instances of exactly the same declared type which it has as a supertype:

object SomeObject : List<Int> by listOf() { ... } SomeObject == listOf(1, 2, 3) // OK SomeObject == arrayListOf(1, 2, 3) // not resolved (why?) object MyObject : Any() { ... } MyObject == 1 // error MyObject == 1 as Any // OK o_O object AnotherObject { ... } AnotherObject == 1 as Any // works! Probably Any is supertype here 

As to defining equals as an extension function: no, you can't do it because extensions are resolved statically and are shadowed by members (there's a similar question about toString).

Sign up to request clarification or add additional context in comments.

Comments

2

i think your implementation is the right approach

consider this:

class MyClass { companion object { private val NUMBER: Int = 5 private val STRING: String = "foo" override fun equals(other: Any?): Boolean { when(other){ is MyClass -> { return this.NUMBER == other.NUMBER && this.STRING == other.STRING } else -> return false } } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.