Polymorphism

 <  Day Day Up  >  

Polymorphism literally means many shapes . Although polymorphism is tightly coupled to inheritance, it is often cited separately as one of the most powerful advantages to object-oriented technologies. When a message is sent to an object, the object must have a method defined to respond to that message. In an inheritance hierarchy, all subclasses inherit the interfaces from their superclass. However, because each subclass is a separate entity, each might require a separate response to the same message. For example, consider the Shape class and the behavior called Draw . When you tell somebody to draw a shape, the first question he asks is "What shape?" He cannot draw a shape, as it is an abstract concept (in fact, the Draw() method in the Shape code following contains no implementation). You must specify a concrete shape. To do this, you provide the actual implementation in Circle . Even though Shape has a Draw method, Circle overrides this method and provides its own Draw() method. Overriding basically means replacing an implementation of a parent with one from a child.

For example, suppose you have an array of three shapes ” Circle , Square , and Star . Even though you treat them all as Shape objects, and send a Draw message to each Shape object, the end result is different for each because Circle , Square , and Star provide the actual implementations . In short, each class is able to respond differently to the same Draw method and draw itself. This is what is meant by polymorphism.

Consider the following Shape class:

 
 public abstract class Shape{     private double area;     public abstract double getArea(); } 

The Shape class has an attribute called area that holds the value for the area of the shape. The method getArea() includes an identifier called abstract . When a method is defined as abstract , a subclass must provide the implementation for this method; in this case, Shape is requiring subclasses to provide a getArea() implementation. Now let's create a class called Circle that inherits from Shape (the extends keyword signifies that Circle inherits from Shape ):

 
 public class Circle extends Shape{     double radius;     public Circle(double r) {         radius = r;     }     public double getArea() {         area = 3.14*(radius*radius);         return (area);     }; } 

We introduce a new concept here called a constructor . The Circle class has a method with the same name , Circle . When the names are the same and no return type is provided, the method is a special method, called a constructor. Consider a constructor the entry point for the class, where the object is constructed ; the constructor is a good place to perform initializations.

The Circle constructor accepts a single parameter, representing the radius, and assigns it to the radius attribute of the Circle class.

The Circle class also provides the implementation for the getArea method, originally defined as abstract in the Shape class.

We can create a similar class, called Rectangle :

 
 public class Rectangle extends Shape{     double length;     double width;     public Rectangle(double l, double w){         length = l;         width = w;     }     public double getArea() {         area = length*width;         return (area);     }; } 

Now we can create any number of rectangles, circles, and so on, and invoke their getArea() method. This is because we know that all rectangles and circles inherit from Shape, and all Shape classes have a getArea() method. If a subclass inherits an abstract method from a superclass, it must provide a concrete implementation of that method, or else it will be an abstract class itself (see Figure 1.18 for a UML diagram).

Figure 1.18. Shape UML diagram.

graphics/01fig18.gif

Thus, we can instantiate the Shape classes in this way:

 
 Circle circle = new Circle(5); Rectangle rectangle = new Rectangle(4,5); 

Then, using a construct such as a stack, we can add these Shape classes to the stack:

 
 stack.push(circle); stack.push(rectangle); 

What Is a Stack?

A stack is a data structure that is a last-in, first-out system. It is like a coin changer, where you insert coins at the top of the cylinder and, when you need a coin, you simply take one off the top, which is the last one you inserted. Pushing an item onto the stack means that you are adding an item to the top (like inserting another coin into the changer). Popping an item off the stack means that you are taking the last item off the stack (like taking the coin off the top).


Now comes the fun part. We can empty the stack, and we do not have to care about what kind of Shape classes are in it:

 
 while (  !stack.empty()) {     Shape shape = (Shape) stack.pop();     System.out.println ("Area = " + shape.getArea()); } 

In reality, we are sending the same message to all the shapes:

 
 shape.getArea() 

However, the actual behavior that takes place depends on the type of shape. For example, Circle will calculate the area for a circle, and Rectangle will calculate the area of a rectangle. In effect (and here is the key concept), we are sending a message to the Shape classes and experiencing different behavior depending on what subclass of Shape is being used.

 <  Day Day Up  >  


Object-Oriented Thought Process
Object-Oriented Thought Process, The (3rd Edition)
ISBN: 0672330164
EAN: 2147483647
Year: 2003
Pages: 164
Authors: Matt Weisfeld

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