I know method overloading means defining a method in a subclass with the same name as in parent class but with different parameters and method overriding means defining a method in a subclass with the same signature as in parent class.
However, I feel I miss some understanding. I tried some examples. I defined two classes A
and B extends A
. Then I prepared many examples with different combinations of two methods (method(A)
and method(B)
) they can contain. For example:
- Example 1:
A
contains bothmethod(A)
andmethod(B)
andB
contains none - Example 2:
A
containsmethod(A)
andB
containsmethod(B)
and so on. There can be 16 such combinations.
Now I created two instances of class B
and called various methods in the first instance. I can go for creating various combinations of instance types, reference types and method calls also but that will be an overwhelming number of combinations to prepare examples.
Doubt is I am struggling to guess what will be the outputs of some examples. Or more specifically I miss understanding or should I say a minimal set of rules which can dictate what will be the output in all examples. The confusion is arising from the fact that reference type is different from the type of instance it is referring to. So I didn't get which method gets precedence, one which is in reference type or one which is in instance type. In the below examples, I didn't get an output of examples 3, 4 and 5. These are only 5 combinations out of possible 16. I believe there might be some more confusing combinations.
Below are some examples
Example 1 – downcasting gives compile time error
class A {
public void method(B b)
{
System.out.println("A's method(B)");
}
}
class B extends A {
public void method(B b)
{
System.out.println("B's method(B)");
}
}
A a = new B();
B b = new B();
a.method(b); //outputs B's method(B)
a.method(a); //compile time error: The method method(B) in the type A
//is not applicable for the arguments (A)
Example 2 – upcasting may happen if desired
class A {
public void method(A a)
{
System.out.println("A's method(A)");
}
}
class B extends A {
public void method(A a)
{
System.out.println("B's method(A)");
}
}
A a = new B();
B b = new B();
a.method(b);
a.method(a);
Output
B's method(A) //upcasting happening
B's method(A)
Example 3
class A {
public void method(A a)
{
System.out.println("A's method(A)");
}
public void method(B b)
{
System.out.println("A's method(B)");
}
}
class B extends A {
public void method(A a)
{
System.out.println("B's method(A)");
}
}
A a = new B();
B b = new B();
a.method(b);
a.method(a);
Output
A's method(B)
B's method(A)
Example 4
class A {
public void method(A a)
{
System.out.println("A's method(A)");
}
public void method(B b)
{
System.out.println("A's method(B)");
}
}
class B extends A {
public void method(A a)
{
System.out.println("B's method(A)");
}
public void method(B b)
{
System.out.println("B's method(B)");
}
}
A a = new B();
B b = new B();
a.method(b);
a.method(a);
Output
B's method(B)
B's method(A)
Example 5
class A {
public void method(A a)
{
System.out.println("A's method(A)");
}
}
class B extends A {
public void method(A a)
{
System.out.println("B's method(A)");
}
public void method(B b)
{
System.out.println("B's method(B)");
}
}
A a = new B();
B b = new B();
a.method(b);
a.method(a);
Output
B's method(A)
B's method(A)