C#
  Home arrow C# arrow Polymorphism in C#
Iron Speed
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
ASP Web Hosting  
ASP.NET Web Hosting 
Dedicated Servers 
Download TestComplete 
Windows Web Hosting
 
IBM® developerWorks 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
IBM Developerworks
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
C#

Polymorphism in C#
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 19
    2007-05-17

    Table of Contents:
  • Polymorphism in C#
  • Versioning with new and override
  • Abstract Classes
  • The Root of All Classes: Object
  • Boxing and Unboxing Types
  • Summary

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    Iron Speed
     
    ADVERTISEMENT

    Ajax Application Generator Generate database and reporting .NET Web apps in minutes. Quickly create visually stunning, feature-rich apps that are easy to customize and ready to deploy. Download Now!

    Polymorphism in C#
    (Page 1 of 6 )

    In the previous article, we looked at inheritance in C#. In this article, we will look at the concept of polymorphism. It is excerpted from chapter 11 of Learning C# 2005, Second Edition, written by Jesse Liberty and Brian MacDonald (O'Reilly, 2006; ISBN: 0596102097). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

    Polymorphism

    There are two powerful aspects to inheritance. One is code reuse. When you create a ListBox class, you’re able to reuse some of the logic in the base (Window) class.

    What is arguably more powerful, however, is the second aspect of inheritance: polymorphism. Poly means many and morph means form. Thus, polymorphism refers to being able to use many forms of a type without regard to the details.

    When the phone company sends your phone a ring signal, it does not know what type of phone is on the other end of the line. You might have an old-fashioned Western Electric phone that energizes a motor to ring a bell, or you might have an electronic phone that plays digital music.

    As far as the phone company is concerned, it knows only about the “base type” phone and expects that any “derived” instance of this type knows how to ring. When the phone company tells your phone to ring, it, effectively, calls your phone’s ring method, and old fashioned phones ring, digital phones trill, and cutting-edge phones announce your name. The phone company doesn’t know or care what your individual phone does; it treats your telephone polymorphically.

    Creating Polymorphic Types

    Because a ListBox is a Windowand aButtonis a Window, you expect to be able to use either of these types in situations that call for a Window. For example, a form might want to keep a collection of all the derived instances of Window it manages (buttons, lists, and so on), so that when the form is opened, it can tell each of its Windows to draw itself. For this operation, the form does not want to know which elements areListBoxes and which areButtons; it just wants to tick through its collection and tell each one to “draw.” In short, the form wants to treat all its Window objects polymorphically.

    You implement polymorphism in two steps:

    1. Create a base class with virtual methods.
    2. Create derived classes that override the behavior of the base class’s virtual methods.

    To create a method in a base class that supports polymorphism, mark the method asvirtual. For example, to indicate that the methodDrawWindow()of class Window in Example 11-1 is polymorphic, add the keywordvirtual to its declaration, as follows:

      public virtual void DrawWindow()

    Each derived class is free to inherit and use the base class’sDrawWindow()method as is or to implement its own version ofDrawWindow(). If a derived class does override theDrawWindow()method, that overridden version will be invoked for each instance of the derived class. You override the base class virtual method by using the keyword override in the derived class method definition, and then add the modified code for that overridden method.

    Example 11-2 shows how to override virtual methods.

    Example 11-2. Virtual methods

    using System;

    public class Window
    {
       // constructor takes two integers to
       // fix location on the console
       public Window( int top, int left )
       {
         
    this.top = top;
          this.left = left;
       }

       // simulates drawing the window
       public virtual void DrawWindow()
       {
         
    Console.WriteLine( "Window: drawing Window at {0}, {1}",
          top, left );
       }

       // these members are protected and thus visible
       // to derived class methods. We'll examine this
       // later in the chapter. (Typically, these would be private
       // and wrapped in protected properties, but the current approach
       // keeps the example simpler.)
       protected int top;
       protected int left;

    } // end Window

    // ListBox derives from Window
    public class ListBox : Window
    {
      
    // constructor adds a parameter
       // and calls the base constructor
       public ListBox(
       int top,
       int left,
       string contents ) : base( top, left )
       {
         
    listBoxContents = contents;
       }

       // an overridden version (note keyword) because in the
       // derived method we change the behavior
       public override void DrawWindow()
       {
         
    base.DrawWindow(); // invoke the base method
         
    Console.WriteLine( "Writing string to the listbox: {0}",
          listBoxContents );
       }

       private string listBoxContents; // new member variable
    }  // end ListBox

    public class Button : Window
    {
       public Button(
       int top,
       int left ) : base( top, left )
       {}
     

       // an overridden version (note keyword) because in the
       // derived method we change the behavior
       public override void DrawWindow()
       {
         
    Console.WriteLine( "Drawing a button at {0}, {1}\n",
          top, left );
       }
    }  // end Button

    public class Tester
    {
       static void Main()
       {
         
    Window win = new Window( 1, 2 );
          ListBox lb = new ListBox( 3, 4, "Stand alone list box" );
          Button b = new Button( 5, 6 );
          win.DrawWindow();
          lb.DrawWindow();
          b.DrawWindow();

          Window[] winArray = new Window[3];
          winArray[0] = new Window( 1, 2 );
          winArray[1] = new ListBox( 3, 4, "List box in array" );
          winArray[2] = new Button( 5, 6 );

          for ( int i = 0; i < 3; i++ )
          {
             winArray[i].DrawWindow();
          }   // end for
       }   // end Main
    }      // end Tester

    The output looks like this:

      Window: drawing Window at 1, 2
      Window: drawing Window at 3, 4
      Writing string to the listbox: Stand alone list box
      Drawing a button at 5, 6
     
    Window: drawing Window at 1, 2
      Window: drawing Window at 3, 4
      Writing string to the listbox: List box in array
      Drawing a button at 5, 6

    In Example 11-2,ListBox derives from Window and implements its own version ofDrawWindow():

      public override void DrawWindow()
      {
          base.DrawWindow(); // invoke the base method
          Console.WriteLine ("Writing string to the listbox: {0}",
          listBoxContents);
      }

    The keywordoverridetells the compiler that this class has intentionally overridden howDrawWindow()works. Similarly, you’ll overrideDrawWindow()in another class that derives fromWindow: theButton class.

    In the body of the example, you create three objects: aWindow, aListBox, and aButton. Then you callDrawWindow()on each:

      Window win = new Window(1,2);
      ListBox lb = new ListBox(3,4,"Stand alone list box");
      Button b = new Button(5,6);
      win.DrawWindow();
      lb.DrawWindow();
      b.DrawWindow();

    This works much as you might expect. The correctDrawWindow()method is called for each. So far, nothing polymorphic has been done (after all, you called theButtonversion ofDrawWindowon aButtonobject). The real magic starts when you create an array ofWindowobjects.

    Because aListBoxis a Window, you are free to place aListBoxinto an array ofWindows. Similarly, you can add aButton to a collection ofWindows, because aButtonis a Window.

      Window[] winArray = new Window[3];
      winArray[0] = new Window(1,2);
      winArray[1] = new ListBox(3,4,"List box in array");
      winArray[2] = new Button(5,6);

    The first line of code declares an array namedwinArray that will hold threeWindowobjects. The next three lines add newWindowobjects to the array. The first adds an object of typeWindow. The second adds an object of typeListBox(which is aWindow becauseListBoxderives fromWindow), and the third adds an object of typeButton, which is also a type ofWindow.

    What happens when you callDrawWindow()on each of these objects?

      for (int i = 0; i < winArray.Length-1; i++)
      {
        winArray[i].DrawWindow();
      }

    This code usesias a counter variable. It callsDrawWindow()on each element in the array in turn. The valueiis evaluated each time through the loop, and that value is used as an index into the array.

    All the compiler knows is that it has threeWindowobjects and that you’ve calledDrawWindow()on each. If you had not markedDrawWindow()asvirtual,Window’s originalDrawWindow()method would be called three times.

    However, because you did markDrawWindow()as virtual, and because the derived classes override that method, when you callDrawWindow()on the array, the right thing happens for each object in the array. Specifically, the compiler determines the runtime type of the actual objects (aWindow, aListBox, and aButton) and calls the right method on each. This is the essence of polymorphism.

    The runtime type of an object is the actual (derived) type. At compile time, you do not have to decide what kind of objects will be added to your collection, so long as they all derive from the declared type (in this case,Window). At runtime, the actual type is discovered and the right method is called. This allows you to pick the actual type of objects to add to the collection while the program is running.

    Note that throughout this example, the overridden methods are marked with the keywordoverride:

      public override void DrawWindow()

    The compiler now knows to use the overridden method when treating these objects polymorphically. The compiler is responsible for tracking the real type of the object and for handling the late binding, so thatListBox.DrawWindow()is called when the Window reference really points to aListBox object.

    More C# Articles
    More By O'Reilly Media


       · This article is an excerpt from the book "Learning C# 2005, Second Edition,"...
     

    Buy this book now. This article is excerpted from chapter 11 of Learning C# 2005, Second Edition, written by Jesse Liberty and Brian MacDonald (O'Reilly, 2006; ISBN: 0596102097). Check it out today at your favorite bookstore. Buy this book now.

    C# ARTICLES

    - Value Types and Reference Types
    - Defining Member and Type Visibility
    - Managing Files in C#
    - Working with Windows Registry in C#
    - Lossless Image Resizing in C#
    - Lossless Image Converting in C#
    - Creating an RSS Feed with ASP.Net Written in...
    - Polymorphism in C#
    - Inheritance in C#
    - C# Events Explained
    - C# Delegates Explained
    - C# StreamReader and StreamWriter Explained
    - C# FileStream Explained
    - A Look at C# File and FileInfo Classes
    - A Look at C# Directory and DirectoryInfo Cla...

     
    Accelerating Trading Partner Performance
     
    Competing on Analytics
     
    Cost Effective Scaling with Virtualization and Coyote Point Systems
     
    Five Checkpoints to Implementing IP Telephony
     
    Hosted Email Security: Staying Ahead of New Threats
     




    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 1 hosted by Hostway