Abstract Classes and Methods

When we think of a class type, we assume that applications will create objects of that type. In some cases, however, it is useful to declare classes for which the programmer never intends to instantiate objects. Such classes are called abstract classes. Because they are used only as base classes in inheritance hierarchies, we refer to them as abstract base classes. These classes cannot be used to instantiate objects, because as you will soon see, abstract classes are incompletederived classes must declare the "missing pieces." We demonstrate abstract classes in Section 11.5.1.

The purpose of an abstract class is primarily to provide an appropriate base class from which other classes can inherit, and thus share a common design. In the Shape hierarchy of Fig. 10.3, for example, derived classes inherit the notion of what it means to be a Shapecommon attributes such as location, color and borderThickness, and behaviors such as Draw, Move, Resize and ChangeColor. Classes that can be used to instantiate objects are called concrete classes. Such classes provide implementations of every method they declare (some of the implementations can be inherited). For example, we could derive concrete classes Circle, Square and triangle from abstract base class TwoDimensionalShape. Similarly, we could derive concrete classes Sphere, Cube and Tetrahedron from abstract base class THReeDimensionalShape. Abstract base classes are too general to create real objectsthey specify only what is common among derived classes. We need to be more specific before we can create objects. For example, if you send the Draw message to abstract class TwoDimensionalShape, the class knows that two-dimensional shapes should be drawable, but it does not know what specific shape to draw, so it cannot implement a real Draw method. Concrete classes provide the specifics that make it reasonable to instantiate objects.

Not all inheritance hierarchies contain abstract classes. However, programmers often write client code that uses only abstract base class types to reduce client code's dependencies on a range of specific derived class types. For example, a programmer can write a method with a parameter of an abstract base class type. When called, such a method can be passed an object of any concrete class that directly or indirectly extends the base class specified as the parameter's type.

Abstract classes sometimes constitute several levels of the hierarchy. For example, the Shape hierarchy of Fig. 10.3 begins with abstract class Shape. On the next level of the hierarchy are two more abstract classes, TwoDimensionalShape and THReeDimensionalShape. The next level of the hierarchy declares concrete classes for TwoDimensionalShapes (Circle, Square and TRiangle) and for ThreeDimensionalShapes (Sphere, Cube and TeTRahedron).

You make a class abstract by declaring it with keyword abstract. An abstract class normally contains one or more abstract methods. An abstract method is one with keyword abstract in its declaration, as in

public abstract void Draw(); // abstract method

Abstract methods do not provide implementations. A class that contains abstract methods must be declared as an abstract class even if that class contains concrete (non-abstract) methods. Each concrete derived class of an abstract base class also must provide concrete implementations of the base class's abstract methods. We show an example of an abstract class with an abstract method in Fig. 11.4.

Figure 11.4. Employee abstract base class.

(This item is displayed on pages 520 - 521 in the print version)

 1 // Fig. 11.4: Employee.cs
 2 // Employee abstract base class.
 3 public abstract class Employee
 4 {
 5 private string firstName;
 6 private string lastName;
 7 private string socialSecurityNumber;
 9 // three-parameter constructor
10 public Employee( string first, string last, string ssn )
11 {
12 firstName = first;
13 lastName = last;
14 socialSecurityNumber = ssn;
15 } // end three-parameter Employee constructor
17 // read-only property that gets employee's first name
18 public string FirstName
19 {
20 get
21 {
22 return firstName;
23 } // end get
24 } // end property FirstName
26 // read-only property that gets employee's last name
27 public string LastName
28 {
29 get
30 {
31 return lastName;
32 } // end get
33 } // end property LastName
35 // read-only property that gets employee's social security number
36 public string SocialSecurityNumber
37 {
38 get
39 {
40 return socialSecurityNumber;
41 } // end get
42 } // end property SocialSecurityNumber
43 44 // return string representation of Employee object, using properties 45 public override string ToString() 46 { 47 return string.Format( "{0} {1} social security number: {2}", 48 FirstName, LastName, SocialSecurityNumber ); 49 } // end method ToString 50 51 // abstract method overridden by derived classes 52 public abstract decimal Earnings(); // no implementation here 53 } // end abstract class Employee

Properties can also be declared abstract, then overridden in derived classes with the override keyword, just like methods. This allows an abstract base class to specify common properties of its derived classes. Abstract property declarations have the form:

public abstract PropertyType MyProperty
} // end abstract property

The semicolons after the get and set keywords indicate that we provide no implementation for these accessors. An abstract property may omit implementations for the get accessor, the set accessor or both. Concrete derived classes must provide implementations for every accessor declared in the abstract property. When both get and set accessors are specified (as above), every concrete derived class must implement both. If one accessor is omitted, the derived class is not allowed to implement that accessor. Doing so causes a compilation error.

Constructors and static methods cannot be declared abstract. Constructors are not inherited, so an abstract constructor could never be implemented. Similarly, derived classes cannot override static methods, so an abstract static method could never be implemented.

Software Engineering Observation 11 2

An abstract class declares common attributes and behaviors of the various classes that inherit from it, either directly or indirectly, in a class hierarchy. An abstract class typically contains one or more abstract methods or properties that concrete derived classes must override. The instance variables, concrete methods and concrete properties of an abstract class are subject to the normal rules of inheritance.

Common Programming Error 11 1

Attempting to instantiate an object of an abstract class is a compilation error.

Common Programming Error 11 2

Failure to implement a base class's abstract methods and properties in a derived class is a compilation error unless the derived class is also declared abstract.

Although we cannot instantiate objects of abstract base classes, you will soon see that we can use abstract base classes to declare variables that can hold references to objects of any concrete classes derived from those abstract classes. Applications typically use such variables to manipulate derived class objects polymorphically. Also, you can use abstract base class names to invoke static methods declared in those abstract base classes.

Polymorphism is particularly effective for implementing so-called layered software systems. In operating systems, for example, each type of physical device could operate quite differently from the others. Even so, common commands can read or write data from and to the devices. For each device, the operating system uses a piece of software called a device driver to control all communication between the system and the device. The write message sent to a device driver object needs to be interpreted specifically in the context of that driver and how it manipulates a specific device. However, the write call itself really is no different from the write to any other device in the system: Place some number of bytes from memory onto that device. An object-oriented operating system might use an abstract base class to provide an "interface" appropriate for all device drivers. Then, through inheritance from that abstract base class, derived classes are formed that all behave similarly. The device driver methods are declared as abstract methods in the abstract base class. The implementations of these abstract methods are provided in the derived classes that correspond to the specific types of device drivers. New devices are always being developed, often long after the operating system has been released. When you buy a new device, it comes with a device driver provided by the device vendor. The device is immediately operational after you connect it to your computer and install the device driver. This is another elegant example of how polymorphism makes systems extensible.

It is common in object-oriented programming to declare an iterator class that can traverse all the objects in a collection, such as an array (Chapter 8) or an ArrayList (Chapter 27, Collections). For example, an application can print an ArrayList of objects by creating an iterator object and using it to obtain the next list element each time the iterator is called. Iterators often are used in polymorphic programming to traverse a collection that contains references to objects of various classes in an inheritance hierarchy. (Chapters 2627 present a thorough treatment of C#'s new "generics" capabilities, ArrayList and iterators.) An ArrayList of references to objects of class TwoDimensionalShape, for example, could contain references to objects from derived classes Square, Circle, triangle and so on. Calling method Draw for each TwoDimensionalShape object off a TwoDimensionalShape variable would polymorphically draw each object correctly on the screen.



    Introduction to Computers, the Internet and Visual C#

    Introduction to the Visual C# 2005 Express Edition IDE

    Introduction to C# Applications

    Introduction to Classes and Objects

    Control Statements: Part 1

    Control Statements: Part 2

    Methods: A Deeper Look


    Classes and Objects: A Deeper Look

    Object-Oriented Programming: Inheritance

    Polymorphism, Interfaces & Operator Overloading

    Exception Handling

    Graphical User Interface Concepts: Part 1

    Graphical User Interface Concepts: Part 2


    Strings, Characters and Regular Expressions

    Graphics and Multimedia

    Files and Streams

    Extensible Markup Language (XML)

    Database, SQL and ADO.NET

    ASP.NET 2.0, Web Forms and Web Controls

    Web Services

    Networking: Streams-Based Sockets and Datagrams

    Searching and Sorting

    Data Structures



    Appendix A. Operator Precedence Chart

    Appendix B. Number Systems

    Appendix C. Using the Visual Studio 2005 Debugger

    Appendix D. ASCII Character Set

    Appendix E. Unicode®

    Appendix F. Introduction to XHTML: Part 1

    Appendix G. Introduction to XHTML: Part 2

    Appendix H. HTML/XHTML Special Characters

    Appendix I. HTML/XHTML Colors

    Appendix J. ATM Case Study Code

    Appendix K. UML 2: Additional Diagram Types

    Appendix L. Simple Types


    Visual C# How to Program
    Visual C# 2005 How to Program (2nd Edition)
    ISBN: 0131525239
    EAN: 2147483647
    Year: 2004
    Pages: 600

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