Demonstrating Polymorphic Behavior

Section 9.4 created a commission employee class hierarchy, in which class BasePlusCommissionEmployee inherited from class CommissionEmployee. The examples in that section manipulated CommissionEmployee and BasePlusCommissionEmployee objects by using references to them to invoke their methods. We aimed superclass references at superclass objects and subclass references at subclass objects. These assignments are natural and straightforwardsuperclass references are intended to refer to superclass objects, and subclass references are intended to refer to subclass objects. However, as you will soon see, other assignments are possible.

In the next example, we aim a superclass reference at a subclass object. We then show how invoking a method on a subclass object via a superclass reference invokes the subclass functionalitythe type of the actual referenced object, not the type of the reference, determines which method is called. This example demonstrates the key concept that an object of a subclass can be treated as an object of its superclass. This enables various interesting manipulations. A program can create an array of superclass references that refer to objects of many subclass types. This is allowed because each subclass object is an object of its superclass. For instance, we can assign the reference of a BasePlusCommissionEmployee object to a superclass CommissionEmployee variable because a BasePlusCommissionEmployee is a CommissionEmployeewe can treat a BasePlusCommissionEmployee as a CommissionEmployee.

As you will learn later in the chapter, we cannot treat a superclass object as a subclass object because a superclass object is not an object of any of its subclasses. For example, we cannot assign the reference of a CommissionEmployee object to a subclass BasePlusCommissionEmployee variable because a CommissionEmployee is not a BasePlusCommissionEmployeea CommissionEmployee does not have a baseSalary instance variable and does not have methods setBaseSalary and getBaseSalary. The is-a relationship applies only from a subclass to its direct (and indirect) superclasses, and not vice versa.

It turns out that the Java compiler does allow the assignment of a superclass reference to a subclass variable if we explicitly cast the superclass reference to the subclass typea technique we discuss in greater detail in Section 10.5. Why would we ever want to perform such an assignment? A superclass reference can be used to invoke only the methods declared in the superclassattempting to invoke subclass-only methods through a superclass reference results in compilation errors. If a program needs to perform a subclass-specific operation on a subclass object referenced by a superclass variable, the program must first cast the superclass reference to a subclass reference through a technique known as downcasting. This enables the program to invoke subclass methods that are not in the superclass. We will show you a concrete example of downcasting in Section 10.5.

The example in Fig. 10.1 demonstrates three ways to use superclass and subclass variables to store references to superclass and subclass objects. The first two are straightforwardas in Section 9.4, we assign a superclass reference to a superclass variable, and we assign a subclass reference to a subclass variable. Then we demonstrate the relationship between subclasses and superclasses (i.e., the is-a relationship) by assigning a subclass reference to a superclass variable. [Note: This program uses classes CommissionEmployee3 and BasePlusCommissionEmployee4 from Fig. 9.12 and Fig. 9.13, respectively.]

Figure 10.1. Assigning superclass and subclass references to superclass and subclass variables.

(This item is displayed on pages 464 - 465 in the print version)

 1 // Fig. 10.1: PolymorphismTest.java
 2 // Assigning superclass and subclass references to superclass and
 3 // subclass variables.
 4
 5 public class PolymorphismTest
 6 {
 7 public static void main( String args[] )
 8 {
 9 // assign superclass reference to superclass variable 
10 CommissionEmployee3 commissionEmployee = new CommissionEmployee3(
11  "Sue", "Jones", "222-22-2222", 10000, .06 ); 
12
13 // assign subclass reference to subclass variable 
14 BasePlusCommissionEmployee4 basePlusCommissionEmployee =
15  new BasePlusCommissionEmployee4( 
16  "Bob", "Lewis", "333-33-3333", 5000, .04, 300 ); 
17
18 // invoke toString on superclass object using superclass variable
19 System.out.printf( "%s %s:

%s

",
20 "Call CommissionEmployee3's toString with superclass reference ",
21 "to superclass object", commissionEmployee.toString() );
22
23 // invoke toString on subclass object using subclass variable
24 System.out.printf( "%s %s:

%s

",
25 "Call BasePlusCommissionEmployee4's toString with subclass",
26 "reference to subclass object",
27 basePlusCommissionEmployee.toString() );
28
29 // invoke toString on subclass object using superclass variable
30 CommissionEmployee3 commissionEmployee2 =
31  basePlusCommissionEmployee; 
32 System.out.printf( "%s %s:

%s
",
33 "Call BasePlusCommissionEmployee4's toString with superclass",
34 "reference to subclass object", commissionEmployee2.toString() );
35 } // end main
36 } // end class PolymorphismTest
 
Call CommissionEmployee3's toString with superclass reference to superclass
object:

commission employee: Sue Jones
social security number: 222-22-2222
gross sales: 10000.00
commission rate: 0.06

Call BasePlusCommissionEmployee4's toString with subclass reference to
subclass object:

base-salaried commission employee: Bob Lewis
social security number: 333-33-3333
gross sales: 5000.00
commission rate: 0.04
base salary: 300.00

Call BasePlusCommissionEmployee4's toString with superclass reference to
subclass object:

base-salaried commission employee: Bob Lewis
social security number: 333-33-3333
gross sales: 5000.00
commission rate: 0.04
base salary: 300.00
 

In Fig. 10.1, lines 1011 create a CommissionEmployee3 object and assign its reference to a CommissionEmployee3 variable. Lines 1416 create a BasePlusCommissionEmployee4 object and assign its reference to a BasePlusCommissionEmployee4 variable. These assignments are naturalfor example, a CommissionEmployee3 variable's primary purpose is to hold a reference to a CommissionEmployee3 object. Lines 1921 use reference commissionEmployee to invoke toString explicitly. Because commissionEmployee refers to a CommissionEmployee3 object, superclass CommissionEmployee3's version of toString is called. Similarly, lines 2427 use basePlusCommissionEmployee to invoke toString explicitly on the BasePlusCommissionEmployee4 object. This invokes subclass BasePlusCommissionEmployee4's version of toString.

Lines 3031 then assign the reference to subclass object basePlusCommissionEmployee to a superclass CommissionEmployee3 variable, which lines 3234 use to invoke method toString. A superclass variable that contains a reference to a subclass object and is used to call a method actually calls the subclass version of the method. Hence, commissionEmployee2.toString() in line 34 actually calls class BasePlusCommissionEmployee4's toString method. The Java compiler allows this "crossover" because an object of a subclass is an object of its superclass (but not vice versa). When the compiler encounters a method call made through a variable, the compiler determines if the method can be called by checking the variable's class type. If that class contains the proper method declaration (or inherits one), the compiler allows the call to be compiled. At execution time, the type of the object to which the variable refers determines the actual method to use.

Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look

Arrays

Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams

Recursion

Searching and Sorting

Data Structures

Generics

Collections

Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2

Multithreading

Networking

Accessing Databases with JDBC

Servlets

JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net