Section 11.3. Demonstrating Polymorphic Behavior


11.3. Demonstrating Polymorphic Behavior

Section 10.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 base class references at base class objects and derived class references at derived class objects. These assignments are natural and straightforwardbase class references are intended to refer to base class objects, and derived class references are intended to refer to derived class objects. However, as you will soon see, some "crossover" assignments are possible.

In the next example, we aim a base class reference at a derived class object. We then show how invoking a method on a derived class object via a base class reference invokes the derived class 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 derived class can be treated as an object of its base class, yet still "do the right thing." This enables various interesting manipulations. A program can create an array of base class references that refer to objects of many derived class types. This is allowed because each derived class object is an object of its base class. For instance, we can assign the reference of a BasePlusCommissionEmployee object to a base class CommissionEmployee variable because a BasePlusCommissionEmployee is a CommissionEmployee so we can treat a BasePlusCommissionEmployee as a CommissionEmployee.

As you will learn later in the chapter, we cannot treat a base class object as a derived class object because a base class object is not an object of any of its derived classes. For example, we cannot assign the reference of a CommissionEmployee object to a derived class BasePlusCommissionEmployee variable because a CommissionEmployee is not a BasePlusCommissionEmployeea CommissionEmployee does not have a baseSalary instance variable and does not have property BaseSalary. The is-a relationship applies only from a derived class to its direct (and indirect) base classes, but not vice versa.

The compiler does allow the assignment of a base class reference to a derived class variable if we explicitly cast the base class reference to the derived class typea technique we discuss in detail in Section 11.5. Why would we ever want to perform such an assignment? A base class reference can be used to invoke only the methods declared in the base class attempting to invoke derived-class-only methods through a base class reference results in compilation errors. If a program needs to perform a derived class-specific operation on a derived class object referenced by a base class variable, the program must first cast the base class reference to a derived class reference through a technique known as downcasting. This enables the program to invoke derived class methods that are not in the base class, but only off a derived class reference. We demonstrate downcasting in Section 11.5.

Figure 11.1 shows three ways to use base class and derived class variables to store references to base class and derived class objects. The first two are straightforwardas in Section 10.4, we assign a base class reference to a base class variable, and we assign a derived class reference to a derived class variable. Then we demonstrate the relationship between derived classes and base classes (i.e., the is-a relationship) by assigning a derived class reference to a base class variable. [Note: This program uses the CommissionEmployee and BasePlusCommissionEmployee classes from Fig. 10.13 and Fig. 10.14, respectively.]

Figure 11.1. Assigning base class and derived class references to base class and derived class variables.

 1  ' Fig. 11.1: PolymorphismTest.vb  2  ' Assigning base class and derived class references to base class and  3  ' derived class variables.  4  Module PolymorphismTest  5     Sub Main()  6        Dim commissionEmployee1 As CommissionEmployee  7        Dim basePlusCommissionEmployee As BasePlusCommissionEmployee  8  9        ' assign base class reference to base class variable 10        commissionEmployee1 = New CommissionEmployee( __     11           "Sue", "Jones", "222-22-2222", 10000, 0.06D) 12 13        ' assign derived class reference to derived class variable      14        basePlusCommissionEmployee = New BasePlusCommissionEmployee( __ 15           "Bob", "Lewis", "333-33-3333", 5000, 0.04D, 300)             16 17        ' invoke ToString on base class object using base class variable 18        Console.WriteLine("Call CommissionEmployee's ToString with " & __ 19           "base class reference to base class object: " & vbCrLf & __ 20           commissionEmployee1.ToString() & vbCrLf ) 21 22        ' invoke ToString on derived class object using 23        ' derived class variable 24        Console.WriteLine("Call BasePlusCommissionEmployee's ToString " & __ 25           "with derived class reference to derived class object: " & __ 26           vbCrLf & basePlusCommissionEmployee.ToString() & vbCrLf) 27 28        ' assign derived class reference to base class variable 29        Dim commissionEmployee2 As CommissionEmployee = __      30           basePlusCommissionEmployee                           31 32        ' invoke ToString on derived class object using base class variable 33        Console.WriteLine("Call BasePlusCommissionEmployee's ToString " & __ 34           "with base class reference to derived class object: " & __ 35           vbCrLf & commissionEmployee2.ToString()) 36     End Sub ' Main 37  End Module ' PolymorphismTest

[View full width]

Call CommissionEmployee's ToString with base class reference to base class object: commission employee: Sue Jones social security number: 222-22-2222 gross sales: 10,000.00 commission rate: 0.06 Call BasePlusCommissionEmployee's ToString with derived class reference to derived class object: commission employee: Bob Lewis social security number: 333-33-3333 gross sales: 5,000.00 commission rate: 0.04 base salary: 300.00 Call BasePlusCommissionEmployee's ToString with base class reference to derived class object: commission employee: Bob Lewis social security number: 333-33-3333 gross sales: 5,000.00 commission rate: 0.04 base salary: 300.00



In Fig. 11.1, lines 1011 create a CommissionEmployee object and assign its reference to a CommissionEmployee variable. Lines 1415 create a BasePlusCommissionEmployee object and assign its reference to a BasePlusCommissionEmployee variable. These assignments are naturalfor example, a CommissionEmployee variable's primary purpose is to hold a reference to a CommissionEmployee object. Lines 1820 use reference commissionEmployee1 to invoke ToString explicitly. Because commissionEmployee1 refers to a CommissionEmployee object, base class CommissionEmployee's version of ToString is called, as is evident from the output. Similarly, lines 2426 use basePlusCommissionEmployee to invoke ToString explicitly on the BasePlusCommissionEmployee object. This invokes derived class BasePlusCommissionEmployee's version of ToString, as is also evident from the output.

Lines 2930 then assign to a base class CommissionEmployee variable commissionEmployee2 the reference to derived class object basePlusCommissionEmployee, which lines 3335 use to invoke method ToString. A base class variable that contains a reference to a derived class object and that is used to call a method (which is in both the base class and the derived class) actually calls the derived class version of the method (polymorphically). Hence, commissionEmployee2.ToString() in line 35 actually calls class BasePlusCommissionEmployee's ToString method. The compiler allows this "crossover" because an object of a derived class is an object of its base class (but not vice versa). When the compiler encounters a method call made through a variable, it determines whether 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 version of the method to use. This is polymorphic behavior.



Visual BasicR 2005 for Programmers. DeitelR Developer Series
Visual Basic 2005 for Programmers (2nd Edition)
ISBN: 013225140X
EAN: 2147483647
Year: 2004
Pages: 435

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