No answer so far gets to the heart of the issue.
Java's typing system is covariant (until you get to generics, where you choose which variance you want).
Given that class Apple extends Fruit
and class Fruit extends Object
, then all Apples are also Fruits, all Fruits are also Objects, and all Apples are also Objects.
And Object, because java.lang.Object
says so, has an equals(Object other)
method. That means that apples must also have this method:
- All apples are objects.
- All objects have an
equals(Object)
method
- Therefore, apples have an
equals(Object)
method.
So why do objects have this method? Because it's useful. Because it makes ArrayList
's contains(Object other)
method tick, it makes java.util.Set work. Once you've decided that all Objects have an equals(Object other)
method, the rest (specifically, that apples have an equals(Object other)
method, which trivially returns false if you ask it if it is equal to some non-apple object) is locked in; that is now the case simply because the system we've set up here (which is a covariant typing system, where the base type all types inherit from has an equals(Object)
method) dictates it must be so.
Yes, the java language spec in fact guarantees it; you can't 'remove' the equals(Object)
method from Apples. However, the crux of the matter is why the java spec works like this.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…