I've been studying because I have an exam and I don't have many problems with most of Java but I stumbled upon a rule I can't explain. Here's a code fragment:
public class A { public int method(Object o) { return 1; } public int method(A a) { return 2; } } public class AX extends A { public int method(A a) { return 3; } public int method(AX ax) { return 4; } } public static void main(String[] args) { Object o = new A(); A a1 = new A(); A a2 = new AX(); AX ax = new AX(); System.out.println(a1.method(o)); System.out.println(a2.method(a1)); System.out.println(a2.method(o)); System.out.println(a2.method(ax)); }
This returns:
1 3 1 3
While I would expect it to return:
1 3 1 4
Why is it that the type of a2 determines which method is called in AX?
I've been reading on overloading rules and inheritance but this seems obscure enough that I haven't been able to find the exact rule. Any help would be greatly appreciated.
In the inheritance hierarchy, superclass and subclass methods can be overridden and overloaded.
Method overloading in java is based on the number and type of the parameters passed as an argument to the methods. We can not define more than one method with the same name, Order, and type of the arguments. It would be a compiler error.
To override an inherited method, the method in the child class must have the same name, parameter list, and return type (or a subclass of the return type) as the parent method. Overloading a method is when several methods have the same name but the parameter types, order, or number are different.
Method Overloading Rules Two methods will be treated as overloaded if both follow the mandatory rules below: Both must have the same method name. Both must have different argument lists.
The behavior of these method calls is dictated and described by the Java Language Specification (reference section 8.4.9).
When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2). If the method that is to be invoked is an instance method, the actual method to be invoked will be determined at run time, using dynamic method lookup (§15.12.4).
In your example, the Java compiler determines the closest match on the compile type of the instance you are invoking your method on. In this case:
A.method(AX)
The closest method is from type A, with signature A.method(A)
. At runtime, dynamic dispatch is performed on the actual type of A (which is an instance of AX), and hence this is the method that is actually called:
AX.method(A)
I will clarified it in more simple way. See when you making sub class object with super class reference like here you did.
Always one thing keep in your mind that when you call with super class reference, no matters object is of sub class it will go to the super class, check method with this name along with proper signature is there or not.
now if it will find it, than it will check whether it is overridden?? if yes than it will go to the sub class method like here it went. another wise it will execute the same super class method.
I can give you the example of it...just hide
public int method(A a) { return 3; }
method & check your answer you will get 1 2 1 2, why because it gives first priority to reference. because you overridden it & than calling it, so its giving 3..!! hope its big but easy to understand. Happy Learning
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With