See here:
Returns true
if this vector contains the specified element. More formally, returns true
if and only if this vector contains at least one element e
such that (o==null ? e==null : o.equals(e))
.
The .equals
that ends up being called is the overridden .equals
. The fact that the method parameter is typed with Object
doesn't mean that the vector will use .equals
method of the Object
class; it will use the overridden .equals
method if one exists (otherwise using the one inherited from Object
). The parameter being typed Object
just means that you can pass in anything that is an Object
(which String
is, since all Java classes inherit from Object
).
Your confusion stems from the fact that the method invoked at runtime depends on the actual type of the object whose method is being invoked. Look at the JLS section on runtime evalution of method invocations for more details. You can see that it mentions a "target reference", which is the object whose method you are invoking.
Consider what would happen otherwise: behavior would change based on the type of the method parameter, rather than the type of the instance. This would completely defeat polymorphism! Consider the oft-used Animal
example: let's say there is a single method called makeNoise()
that returns the string "Noise!"
. Now you have two subclasses Dog
and Cat
that have overridden the method to return "Woof!"
and "Meow!"
respectively. Let's now say you have this method:
public void animalNoiseMaker(Animal animal) {
System.out.println(animal.makeNoise());
}
Going by your expectation, regardless of whether you passed in a Dog
or Cat
instance, it would call makeNoise
on Animal
every time and print Noise!
because the parameter type is Animal
. This is not very useful behavior.