In these demos we use the StartApplet3.java
starter, which includes a class called Test
and its subclass Test1,
which in turn is subclassed by Test2.
In the first demo, each subclass overrides a method in its corresponding
superclass. In the Applet
class init()
we use an array of the Test
type to reference instances of Test
and the two subclasses.
Cycling through the the Test
array in a loop we invoke the aMethod.
You will see in the printout that the overriding aMethod
of the particular subclass object is invoked, not the aMethod
in the Test
base class.
This demonstrates the powerful, so-called, polymorphic quaility
of objects in that an object can be referenced as its superclass
yet act according to its own class.
|
OverrideApplet.java
(Output goes to browser's Java
console.)
|
public
class OverrideApplet extends java.applet.Applet
{
public void init () {
Test [] array = new Test[3];
array[0] = new Test ();
array[1] = new Test1 ();
array[2] = new Test2 ();
for (int i=0; i<3; i++) {
array[i].aMethod
();
}
}
// Paint message in Applet window.
public void paint (java.awt.Graphics g) {
g.drawString ("OverrideApplet",10,20);
}
} // class OverrideApplet
/** Use Test to examine various aspects of class design.
**/
class Test
{
void aMethod () {
System.out.println ("In Test aMethod");
}
}
/** Test 1 is a sub-class of Test. **/
class Test1 extends Test
{
void aMethod () {
System.out.println ("In Test1 aMethod");
}
}
/** And Test2 is a sub-class of Test1. **/
class Test2 extends Test1
{
void aMethod () {
System.out.println ("In Test2 aMethod");
}
}
|
In the second demo, each of the "Test#"
classes overloads its aMethod()
and each of the subclasses also overrides one of the versions of
aMethod()
in its corresponding superclass.
In the Applet
class init()
we create an instance of the Test2
type and then call each of the different aMethod()
versions.
Before looking at the printout on the Java console,
write down what you think it will show.
|
RideLoadApplet.java
(Output goes to browser's Java
console.)
|
public
class RideLoadApplet extends java.applet.Applet
{
public void init () {
Test2 test2 = new Test2 ();
test2.aMethod ();
test2.aMethod (4.5);
test2.aMethod (4);
test2.aMethod (true);
}
// Paint message in Applet window.
public void paint (java.awt.Graphics g) {
g.drawString ("RideLoadApplet",
20, 20);
}
}
/** Base class. **/
class Test
{
void aMethod () {
System.out.println ("In Test aMethod");
}
void aMethod (double d) {
System.out.println ("In Test aMethod
(double d)");
}
}
/** Test1 is a subclass of Test. **/
class Test1 extends Test
{
void aMethod (int i) {
System.out.println ("In Test1 aMethod
(int i)");
}
void aMethod (boolean b) {
System.out.println ("In Test1 aMethod
(boolean b)");
}
}
/** And Test2 is a subclass of Test1. **/
class Test2 extends Test1
{
void aMethod () {
System.out.println ("In Test2 aMethod
()");
}
void aMethod (boolean b) {
System.out.println ("In Test2 aMethod
(boolean b)");
}
}
|
Note that you must be careful with integer and floating
point arguments in overriding and overloading due to the different
rules regarding conversions from integer to floating point and
floating point to integer. (See Chapter
2: Casting and Mixing)
In this case, if the aMethod(double
d) had been put into Test1
and
void aMethod(int i) in Test,
the compiler would complain of an ambiguity:
Error: reference
to aMethod is ambiguous, both method aMethod(int) in Test and
method aMethod(double) in Test1 match test2.aMethod(4);
The test2.aMethod(4)
invocation would fit the argument list of the
aMethod(double d) in Test1
since an integer can convert to a double without a cast. But then
as the compiler looked further in the method stack, it would
find also the aMethod(int
i) in Test.
As currently composed, the compiler first finds the
aMethod(int
i) in Test1
and since the match is exact, doesn't look farther.
Latest Update: Oct. 21, 2004
|