Polymorphism

 <  Day Day Up  >  

Let's say you have reserved a rental car for a trip to San Francisco. You have a confirmation for a car. A midsize car has been requested , but the exact make of the car won't be known until you get to the car rental counter and see what is actually available. But that doesn't preclude you from reserving the car. The actual make of the car will be known at runtime. This is polymorphism. In other words, polymorphism is the ability for objects to act like other objects in the inheritance hierarchy.

What Is It Again?

Polymorphism is an object-oriented mechanism that enables the method version executed to be determined at runtime based on the datatype of the object instance. It lets us use a superclass object datatype, knowing that at runtime, the object datatype will be of a subclass object datatype. We do this because the object datatype can be determined only at runtime.

In our loan calculator application, we use polymorphism. In Listing 5.14, you can see that depending on the user 's selection at runtime, the type of loan could be car or mortgage. The loan instance variable has a static datatype of type Loan . However, at runtime, the loan instance could hold either a Mortgage instance or a CarLoan instance (called dynamic or actual datatype). In either case, the call to getMonthlyPayment( ) is identical.

Listing 5.14. Object Datatyping
 var loan:Loan;  static datatype if (loanType.selectedData == "m"){       loan = new Mortgage(...));  datatype determined at run-time }else{       loan = new CarLoan(...);  datatype determined at run-time } //calculate the monthly payment var monthlyPmtVal:Number =  loan.getMonthlyPayment(); 

How Does It Work?

To better understand polymorphism, we can look at object datatyping and the superclass-subclass relationship. In the process, we will discover how casting, which is the changing of an object from one type to another, plays a key role in polymorphism.

Starting with object datatypes, Figure 5.7 shows a legal assignment with regard to the Loan class hierarchy. Notice that a variable of a superclass datatype can be used to reference an instance of a subclass.

Figure 5.7. Legal object assignment.

graphics/05fig07.gif

When we create a variable of a particular type, the blueprint for that type is loaded and used to validate its usage. Because any subclass has everything its superclass has, there is no problem when a superclass blueprint is used to validate a subclass.

Although there will be many times when you will want to use the superclass datatype to point to a subclass instance, there is one limitation: Only the methods defined in the superclass can be invoked. In Figure 5.7, when we tried to execute a mortgage method, calculatePropertyTax() , the compiler generated an error. The method we want to execute would be that of the actual (dynamic) type of the object and not the method of the reference variable (static) type.

N OTE

In other object-oriented languages, such as Java, the datatype of the reference variable is called the static datatype and the datatype of the instance is called the dynamic datatype. In Figure 5.7, the static datatype is Loan and the dynamic datatype is Mortgage .


Because a subclass can have new members that are not in the superclass, the compiler will complain when we use a subclass reference variable to point to a superclass, as shown in Figure 5.8.

Figure 5.8. Illegal type assignment.

graphics/05fig08.gif

Casting

Another important concept for polymorphism is casting . ActionScript 2.0 lets you cast one datatype to another. The cast operator that Flash uses takes the form of a function. When you cast a variable from one type to another, you are telling the compiler that the actual type of the object will be different at runtime. The compiler treats the object as having a set of properties that its initial datatype does not contain. This can be useful, for example, when iterating over an array of objects that might be of differing types.

N OTE

Casting in ActionScript 2.0 is also referred to as "explicit coercion," as specified in the ECMA-262 Edition 4 proposal.


The syntax for casting is a function syntax, as seen in Figure 5.9. The function call is newtype(instance) where you want the compiler to behave as if the datatype of instance is newtype . Casting is used when the compatibility can be determined only at runtime.

Figure 5.9. Casting example.

graphics/05fig09.gif

N OTE

The casting function call returns null if the cast fails. If the cast succeeds, the function call returns the original object. There is one caveat: The compiler doesn't generate type-mismatch errors when you cast items to datatypes that you have created in external class files, even if the cast will fail at runtime.


In Listing 5.15, we have used polymorphism to calculate and display the loan payments. Notice that this function takes an argument of type Loan .

Listing 5.15. Polymorphism in the calc Method
 function calc(loanInstance:Loan){ //function called by the button handler       //calculate and display the monthly payment       //the actual run-time datatype could be CarLoan or Mortgage       //regardless, getMonthlyPayment() will return the correct results       var monthlyPmtVal:Number =  loanInstance.getMonthlyPayment();       monthlyPmt.text = monthlyPmtVal;       //calculate and display total payments       var totalPmtVal:Number =  loanInstance.getTotalPayment();       totalPmt.text = totalPmtVal; } 

Because we know that the Loan class defines the calculate methods, we can call the methods regardless of the actual datatypes of the class passed in. We know that the actual type of the argument can be either Mortgage or CarLoan , as shown in Listing 5.16.

Listing 5.16. Passing loan to the calc Method
 this.calc_btn.onPress = function(){       var loanInstance:Loan;       if (loanType.selectedData == "m"){             loanInstance = new Mortgage(loanAmt, term, rate); }else{             loanInstance = new CarLoan(loanAmt, term, rate);       }       this._parent.calc(loanInstance); } 

Another example of polymorphism can be seen in Listing 5.17. The Employee and Manager classes both have methods for calculating bonuses. In an application used for handling bonus letters , each object, Employee and Manager , uses different algorithms to calculate bonuses. In Listing 5.17, the object of type Employee is passed and letters are printed. The runtime datatype of the object can be either Employee or Manager .

Listing 5.17. Polymorphism Example
 processBonusLetter(emp:Employee){       var empName = emp.getName();       var empBonus = emp.getBonus();  bonus calculate based on emp type       print(empName, empBonus); } 

For programmers new to OOP, polymorphism can be a challenging concept to grasp. As you gain experience in OOP, polymorphism becomes clearer. In most cases, polymorphism opportunities have a way of exposing themselves rather than being planned into an application.

 <  Day Day Up  >  


Object-Oriented Programming with ActionScript 2.0
Object-Oriented Programming with ActionScript 2.0
ISBN: 0735713804
EAN: 2147483647
Year: 2004
Pages: 162

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