Reputation: 1142
I have these two classes:
public class A {
private final static A five = new A(5);
public final int x;
public A(int x) {
this.x = x;
}
public boolean equals(Object o) {
return x == ((A) o).x;
}
public String toString() {
return equals(five) ? "five" : (x + "");
}
}
public class B extends A {
public final int x;
public B(int x) {
super(x);
this.x = x + 1;
}
public boolean equals(A o) {
return x == o.x;
}
public String toString() {
return "B: " + super.toString();
}
}
These are the 2 lines in my main
program:
System.out.println(new B(5));
System.out.println((new B(5)).equals(new A(5)));
I know that in Java the method called is decided by the Object type,
in both of the lines the Object is of type B
, so in the first line i have a call to B
class toString()
method,
from there after it prints "B: " it calls A
class toString()
, and now it tries to activate the equals()
method.
From my understanding on polymorphism in Java the Object type i still B
, so it will try to activate B
's equals()
method, but actually while debugging it activates the A
class equals()
, that's the first thing i don't understand.
Later in the 2nd line of my main
program i'm initializing a B
Object, and calling the equals()
method, so after i've seen how the first line of code behaves i said well OK, i'll call the A
equals()
but in practice this line goes to B
's equals
...
I'm a bit confused, first the 2 lines of my main
program behaves differently from what i know about how polymorphic code works, and the 2 lines behave differently although they should act the same...
Hope you could enlighten me about how this code works and why.
Upvotes: 2
Views: 84
Reputation: 691755
Your equals() method in B doesn't override the equals() method in A. One takes an Object as argument, and the other takes an A as argument.
When A.toString() is compiled, the compiler looks for a method in A and all its superclasses named equals(), and taking an A of any of its superclasses/interfaces as argument. And the only one existing is A.equals(Object). So that's what toString() uses.
Polymorphism allows choosing the appropriate method at runtime based on the type of the object on which the method is called. Not on the types of the arguments of the method. If a method is overloaded (i.e. several methods with the same name but different argument types exist), the choice of which method to use is made statically, at compilation time.
Upvotes: 2