It also just does not work. You cannot "override" ...
# announcements
d
It also just does not work. You cannot "override" member functions with extension functions. If you use the
==
it will never call an extension function (same if you call
equals
directly), since the
equals
in
Any
always has higher precedence.
b
As a FYI, my use of
Value.equals(Value): Boolean
is representing the method signature, not a
fun Value.equals(other: Value): Boolean
extension function (granted vague since the primary difference is the absence of
fun
)
d
Oh. Well, then I retract my statement 😄
u
Same here
🙂
d
But it still doesn't sound like a great idea at all.
If you override
equals
you must override
hashCode
. Otherwise bad things happen.
u
sure. but what if i overload equals 😉
b
I agree about the overriding. I think the same contract would still exist and be considered during overloads 🙂
u
I agree. But as the same object might be used by it's real type and in another place as an
Any
, results of different
equal
and
hashCode
might get mixed
j
If you overload
equals
, you should also override
equals(Any?)
. The latter probably invokes the overloaded variant at some point. This way everything works, and the compiler can still pick the most suitable one, skipping useless
null
and
is
checks
b
I can see that 🤔 would that be any different than defining
A.plus(a: Any?)
vs
B.plus(b: B)
(given B extends A)
u
The point is that having a generic (Any) and a specific (Value) implementation of equals seem a bad idea because overload resolution happens on the declare type, not the real type and can be different in different parts of your code. And I think equality should not be relative 🙂
@bdawg.io No different from defining
A.plus(a: Any?)
vs
B.plus(b: B)
b
Or more appropriately
compareTo
dispatches to the overloaded methods, but I think greater/less comparisons are just as important as equal value comparisons
j
Yes, they can be different, but I prefer to be able to choose if I want them to be different or not. So I am still interested in knowing whether the limitation is to prevent confusion (which is seemingly not a problem with other operators), or due to technical restrictions
u
I am sure there is a OO-Programming text book that would tell us that it is generally no good idea to write more spefic overloads to more generic implementations from a base class
@jstuyts-squins It would be a problem with other operators if they provided a generic version. For the
plus
-operator it is OK, because there is no generic version (i.e.
A.plus(a: Any?)
)
Not even
A.plus(a: Number)
b
I agree @jstuyts-squins. To me, this seems like either than intentional limitation or an oversight in the consistency of the
==
convention compared to the others
While it would not automatically be imported into other contexts, you can define
operator fun Any.plus(other: Any?): Any
as a valid extension function that would be dispatched to in any context that has it imported
u
I pledge for 'intentional limitation'
👍 1
b
I would pledge for consistency in the way all conventions are dispatched since they are syntax sugar that get converted in the compilation process 🙂 (whether it be overloading or overriding)