Java Reference
In-Depth Information
In the
GenericSub
class, the
m1()
and
m2()
methods override the corresponding methods in the
GenericSuper
class. If you compare the methods
m1()
and
m2()
between Listing 16-41 and Listing 16-43 for overriding rules, you
would think that they do not have the same signature because the code in Listing 16-41 uses generics. The rules
for checking for override equivalent method signature is that if a method uses generic parameters, you need to
compare its erasure, not the generic version of its declaration. When you compare erasure of
m1()
and
m2()
method's
declaration in the
GenericSuper
class (in Listing 16-42) with
m1()
and
m2()
methods declarations in Listing 16-43, you
would find that
m1()
and
m2()
methods are overridden in the
GenericSub
class.
Typo Danger in Method Overriding
Sometimes it is easy to get it wrong when you try to override a method in a class. It may seem that you have overridden
a method when it is not overridden. Let's consider the following two classes,
C1
and
C2
:
// C1.java
package com.jdojo.inheritance;
public class C1 {
public void m1(double num) {
System.out.println("Inside C1.m1(): " + num);
}
}
// C2.java
package com.jdojo.inheritance;
public class C2 extends C1 {
public void m1(int num) {
System.out.println("Inside C2.m1(): " + num);
}
}
The intent was that the
m1()
method in class
C2
overrides the
m1()
method of class
C1
. However, this is not true.
It is a case of method overloading, not method overriding. The
m1()
method in
C2
is overloaded;
m1(double num)
is
inherited from class
C1
and
m1(int num)
is declared in
C2
. Things becomes more difficult when you start running your
program and you do not get the desired results. Consider the following code snippet;
C1 c = new C2();
c.m1(10); // Which method is called - C1.m() or C2.m2()?
What should be printed when you execute the above code? It prints the following:
Inside C1.m1(): 10.0
Are you surprised to see the output of the above snippet of code? Let's discuss in detail what happens when the
above snippet of code is compiled and executed. When the compiler comes across the second statement,
c.m1(10)
,
it does the following thing: it finds out the compile-time type of the reference variable
c
, which is
C1
.
It looks for a method named
m1
in
C1
. The argument value
10
passed to the method
m1()
is an
int
. The compiler
looks for a method named
m1
(inherited or declared) in
C1
, which takes an
int
parameter. It finds that class
C1
has
a method
m1(double num)
, which accepts a
double
parameter. It tries type-widening conversion and finds that
m1(double num)
method in class
C1
can be used for
c.m1(10)
method call. At this time, the compiler binds the
method signature for the call. Note that the compiler binds the method signature, not the method code. The method