Abstract Classes

Many of the inheritance examples so far have defined a class called PdaItem that defines the methods and properties common to Contact, Appointment, and so on, which are type objects that derive from PdaItem. PdaItem is not intended to be instantiated itself, however. A PdaItem instance has no meaning by itself; it has meaning only when it is used as a base classto share default method implementations across the set of data types that derive from it. These characteristics are indicative of the need for PdaItem to be an abstract class. Abstract classes are designed for derivation only. It is not possible to instantiate an abstract class, except in the context of instantiating a class that derives from it.

Beginner Topic: Abstract Classes

Abstract classes represent abstract entities. Their abstract members define what an object derived from an abstract entity should contain, but they don't include the implementation. Often, much of the functionality within an abstract class is unimplemented, and before a class can successfully derive from an abstract class, it needs to provide the implementation for the abstract methods in its abstract base class.

To define an abstract class, C# requires the abstract modifier to the class definition, as shown in Listing 6.18.

Listing 6.18. Defining an Abstract Class

 // Define an abstract class     public abstract class PdaItem                                     {     private string _Name;     public PdaItem(string name)     {         _Name = name;     }    public virtual string Name  {      get{ return _Name; }      set{ _Name = value; }  } } ___________________________________________________________________________ ___________________________________________________________________________ public classProgram {   public voidMain()   {      PdaItem item;      // ERROR:Cannot create an instance of the abstract class      //item = new PdaItem("Inigo Montoya");  } } 

Although abstract classes cannot be instantiated, this restriction is a minor characteristic of an abstract class. Their primary significance is achieved when abstract classes include abstract members. An abstract member is a method or property that has no implementation. Its purpose is to force all derived classes to provide the implementation.

Consider Listing 6.19.

Listing 6.19. Defining Abstract Members

 // Define an abstract class public abstract class PdaItem {   private string _Name;   public PdaItem(string name)   {       _Name = name;   }   public virtual string Name   {       get{ return _Name; }       set{ _Name = value; };   }     public abstract string GetSummary();                                } public class Contact : PdaItem {     public override string Name   {    get    {        return FirstName + " " + LastName;    }    set    {       string names = value.Split(' ');       // Error handling not shown.       FirstName = names[0];       LastName = names[1];    }  }  public string FirstName  {      get { return _FirstName; }      set { _FirstName = value; }  }  private string _FirstName;  public string LastName  {      get { return _LastName; }      set { _LastName = value; }  }  private string _LastName;  public string Address  {     get { return _Address; }     set { _Address = value; }  }  private string _Address;    public override string GetSummary()                         {                                                                                     return string.Format(                             "FirstName: {0}\n"                                             + "LastName: {1}\n"                                            + "Address: {2}", FirstName, LastName, Address);            }                                                                   // ... } 

Listing 6.19 defines the GetSummary() member as abstract, and therefore, it doesn't include any implementation. Then, the code overrides it within Contact and provides the implementation. Because abstract members are supposed to be overridden, such members are automatically virtual and cannot be declared so explicitly. In addition, abstract members cannot be private because derived classes would not be able to see them.

Language Contrast: C++Pure Virtual Functions

C++ allows for the definition of abstract functions using the cryptic notation =0. These functions are called pure virtual functions in C++. In contrast with C#, however, C++ does not require the class itself to have any special declaration. Unlike C#s abstract class modifier, C++ has no class declaration change when the class includes pure virtual functions.

If you provide no GetSummary() implementation in Contact, the compiler will report an error. By declaring an abstract member, the abstract class programmer states that in order to form an "is a" relationship with the base class type (i.e., a PdaItem), it is necessary to implement the abstract members, the members for which the abstract class could not provide an appropriate default implementation.

Beginner Topic: Polymorphism

When the implementation for the same member signature varies between two or more classes, you have a key object-oriented principal: polymorphism. Poly" meaning many and "morph" meaning form, polymorphism refers to the fact that there are multiple implementations of the same signature. And since the same signature cannot be used multiple times within a single class, each implementation of the member signature occurs on a different class.

The idea behind polymorphism is that the object itself knows best how to perform a particular operation. Given multiple types of documents, each document type class knows best how to perform a Print() method for its corresponding document type. Therefore, instead of defining a single print method that includes a switch statement with the special logic to print each document type, with polymorphism you call the Print() method corresponding to the specific type of document you wish to print. For example, calling Print() on a word processing document class behaves according to word processing specifics, and calling the same method on a graphics document class will result in print behavior specific to the graphic. Given the document types, however, all you have to do to print a document is to call Print(), regardless of the type.

Moving the custom print implementation out of a switch statement offers several maintenance advantages. First, the implementation appears in the context of each document type's class rather than in a location far removed; this is in keeping with encapsulation. Second, adding a new document type doesn't require a change to the switch statement. Instead, all that is necessary is for the new document type class to implement the Print() signature.

Abstract members are intended to be a way to enable polymorphism. The base class specifies the signature of the method and the derived class provides implementation (see Listing 6.20).

Listing 6.20. Using Polymorphism to List the PdaItems

 public classProgram {     public voidMain()     {         PdaItem[] pda = new PdaItem[3];         Contact contact = new Contact("Sherlock Holmes");         contact.Address = "221B Baker Street, London, England";         pda[0] = contact;         Appointment appointment =            new Appointment("Soccer tournament");         appointment.StartDateTime = new DateTime(2006, 7, 18);         appointment.EndDateTime = new DateTime(2006, 7, 19);         appointment.Location = "Estádio da Machava"         pda[1] = appointment;         contact = new Contact("Anne Frank");         contact.Address =            "263 Prinsengracht, Amsterdam, Netherlands";         pda[2] = contact;         List(pda);    }    public static void List(PdaItem[] items)    {        // Implemented using polymorphism. The derived        // type knows the specifics of implementing        // GetSummary().        foreach (PdaItem item in items)        {            Console.WriteLine("________");            Console.WriteLine(item.Summary());        }    } } 

The results of Listing 6.20 appear in Output 6.5.

Output 6.5.

  ________ FirstName: Sherlock LastName: Holmes Address: 221B Baker Street, London, England ________ Subject: Soccer tournament Start: 7/18/2006 12:00:00 AM End: 7/19/2006 12:00:00 AM Location: Esta'dio da Machava ________ FirstName: Anne LastName: Frank Address: 263 Prinsengracht, Amsterdam, Netherlands 

In this way, you can call the method on the base class but the implementation is specific to the derived class.

Essential C# 2.0
Essential C# 2.0
ISBN: 0321150775
EAN: 2147483647
Year: 2007
Pages: 185

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