Wednesday, June 16, 2010

Polymorphism

What is polymorphism?

Polymorphism is a word taken from the Greek, meaning "many forms", or words to that effect.

The purpose of polymorphism as it applies to OOP is to allow one name to be used to specify a general class of actions. Within that general class of actions, the specific action that is applied in any particular situation is determined by the type of data involved.

Polymorphism in ActionScript comes into play when inherited methods are overridden to cause them to behave differently for different types of subclass objects.

Overriding versus overloading methods

If you read much in the area of OOP, you will find the words override and overload used frequently. (This lesson deals with overriding methods and does not deal with overloading.)

Some programming languages such as C++, Java, and C# support a concept known as method or constructor overloading. However, ActionScript 3 does not support method or constructor overloading. Overriding a method is an entirely different thing from overloading a method even for those languages that support overloading.

Modify the behavior of an inherited method

Polymorphism can exist when a subclass modifies or customizes the behavior of a method inherited from its superclass in order to meet the special requirements of objects instantiated from the subclass. This is known as overriding a method and requires the use of the override keyword in ActionScript.

Override methods differently for different subclasses

ActionScript supports the notion of overriding a method inherited from a superclass to cause the named method to behave differently when called on objects of different subclasses, each of which extends the same superclass and overrides the same method name.

Example - compute the area of different geometrical shapes

For example, consider the computation of the area of a geometrical shape in a situation where the type of geometrical shape is not known when the program is compiled. Polymorphism is a tool that can be used to handle this situation.

Circle and Rectangle extend Shape

Assume that classes named Circle and Rectangle each extend a class named Shape . Assume that the

Shape class defines a method named area . Assume further that the area method is properly overridden in the Circle and Rectangle classes to return the correct area for a circle or a rectangle respectively.

Three types of objects

In this case, a Circle object is a Shape object because the Circle class extends the Shape class. Similarly, a Rectangle object is also a Shape object.

Therefore, an object of the Shape class, the Circle class, or the Rectangle class can be instantiated and any one of the three can be saved in a variable of type Shape.

Flip a virtual random coin

Assume that the program flips a virtual coin and, depending on the outcome of the flip, instantiates an object of either the Circle class or the Rectangle class and saves it in a variable of type Shape. Assuming that the coin flip is truly random, the compiler cannot possibly know at compile time which type of object will be stored in the variable at runtime.

Two versions of the area method

Regardless of which type of object is stored in the variable, the object will contain two versions of the method named area. One version is the version that is defined in the Shape class, and this version will be the same regardless of whether the object is a circle or a rectangle.

Also, this version can't return a valid area because a general shape doesn't have a valid area. However, if the area method is defined to return a value, even this version must return a value even if it isn't valid. (Other programming languages get around this problem with something called an abstract class, which isn't allowed in ActionScript 3.)

The other version of the area method will be different for a Circle object and a Rectangle object due simply to the fact the algorithm for computing the area of a circle is different from the algorithm for computing the area of a rectangle.

Call the area method on the object

If the program calls the area method on the object stored in the variable of type Shape at runtime, the correct version of the area method will be selected and executed and will return the correct area for the type of object stored in that variable. This is runtime polymorphism based on method overriding.

A more general description of runtime polymorphism

A reference variable of a superclass type can be used to reference an object instantiated from any subclass of the superclass.

If an overridden method in a subclass object is called using a superclass-type reference variable, the system will determine, at runtime, which version of the method to use based on the true type of the object, and not based on the type of reference variable used to call the method.

The general rule

The type of the reference determines the names of the methods that can be called on the object. The actual type of the object determines which of possibly several methods having the same name will be executed.

Selection at runtime

Therefore, it is possible (at runtime) to select among a family of overridden methods and determine which method to execute based on the type of the subclass object pointed to by the superclass-type reference when the overridden method is called on the superclass-type reference.

Runtime polymorphism

In some situations, it is possible to identify and call an overridden method at runtime that cannot be identified at compile time. In those situations, the identification of the required method cannot be made until the program is actually running. This is often referred to as late binding, dynamic binding, or run-time polymorphism.

No comments:

Post a Comment