Anda di halaman 1dari 9

Summary

The following article is the second of a three-part article series that presents definitions and samples
for different Object-Oriented Programming (OOP) concepts and its implementation in .NET. The first
part examined the concepts of classes, objects, and structures. This part examines the concepts of
inheritance, abstraction, and polymorphism. The third and last part will examine the concepts of
interface, multiple interface inheritance, collections, and overloading.

Introduction

In Part 1 of Object-Oriented Programming Concepts and .NET, I defined the concepts of class,
object, and structure. In addition to defining the concepts, I explained real world samples and
presented sample code in C# and VB.NET to create classes and structs. The first article also explains
objects as independent building blocks.

In Part 2 of Object-Oriented Programming Concepts and .NET, I will explain the concepts of
inheritance, abstraction, and polymorphism. I will also present a Unified Model Language (UML) class
diagram to represent an object model that will help as a visual aid to explain some concepts. The
purpose of this article is to explain a series of relationships between objects.

Inheritance

In the real world there are many objects that can be specialized. In OOP, a parent class can inherit
its behavior and state to children classes. This concept was developed to manage generalization and
specialization in OOP and is represented by a is-a relationship.

The following OO terms are commonly used names given to parent and child classes in OOP:

• Superclass: Parent class.


• Subclass: Child class.
• Base class: Parent class.
• Derived class: Child class

The most common real world sample to explain inheritance is the geometric shapes object model.
Squares, circles, triangles, rectangles, pentagons, hexagons, and octagons are geometric shapes.
The following figure shows a sample set of geometric figures:
Figure 1. Geometric shapes.

The concept of generalization in OOP means that an object encapsulates common state an behavior
for a category of objects. The general object in this sample is the geometric shape. Most geometric
shapes have area, perimeter, and color. The concept of specialization in OOP means that an object
can inherit the common state and behavior of a generic object; however, each object needs to define
its own special and particular state an behavior. In Figure 1, each shape has its own color. Each
shape has also particular formulas to calculate its area and perimeter.

Inheritance makes code elegant and less repetitive. If we know that all shapes have color, should we
program a color attribute for each shape? The answer is no! Would it be a better idea to create a
shape class that has a color attribute and to make all the specialized shapes to inherit the color
attribute? The answer is yes!

An object model for this sample could have a shape parent class and a derived class for each specific
shape. The following UML class diagram shows the set of classes needed to model the geometric
shapes sample. Observe the field, properties, and methods for each class:
Figure 2. The Shape class is the parent class. Square, Rectangle, and Circle are derived classes that
inherit from Shape. The triangle-connector in the diagram represents an is-a relationship.

The .NET framework has many base classes. Everything is derived from System.Object. You can
create almost anything you imagine using the built-in functionality provided in the .NET Framework
Class Library.

To create a derived class in C#, the class declaration should be done as:

class child: parent

To create a derived class in VB.NET, the class declaration should be done as:

Class child
Inherits parent
End Class

Multiple inheritance

Multiple inheritance is the possibility that a child class can have multiple parents. Human beings have
always two parents, so a child will have characteristics from both parents.
In OOP, multiple inheritance might become difficult to handle because it allows ambiguity for the
compiler. There are programming languages such as C++ that allow multiple inheritance; however,
other programming languages such as Java and the .NET Framework languages do not allow multiple
inheritance. Multiple inheritance can be emulated in .NET using Multiple Interface Inheritance, which
I will explain in Part 3 of this series.

Sealed class

A sealed class is a class that does not allow inheritance. Some object model designs need to allow
the creation of new instances but not inheritance, if this is the case, the class should be declared as
sealed.

To create a sealed class in C#, the class declaration should be done as:

sealed class Shape

To create a sealed class in VB.NET, the class declaration should be done as:

NonInheritable Class Shape

Abstraction

Abstraction is "the process of identifying common patterns that have systematic variations; an
abstraction represents the common pattern and provides a means for specifying which variation to
use" (Richard Gabriel).

An abstract class is a parent class that allows inheritance but can never be instantiated. Abstract
classes contain one or more abstract methods that do not have implementation. Abstract classes
allow specialization of inherited classes.

Figure 2 shows a Shape class, which is an abstract class. In the real world, you never calculate the
area or perimeter of a generic shape, you must know what kind of geometric shape you have
because each shape (eg. square, circle, rectangle, etc.) has its own area and perimeter formulas.
The parent class shape forces all derived classes to define the behavior for CalculateArea() and
CalculatePerimeter(). Another great example is a bank account. People own savings accounts,
checking accounts, credit accounts, investment accounts, but not generic bank accounts. In this
case, a bank account can be an abstract class and all the other specialized bank accounts inherit
from bank account.

To create an abstract class in C#, the class declaration should be done as:

abstract class Shape

To create an abstract class in VB.NET, the class declaration should be done as:

MustInherit Class Shape

To following code shows a sample implementation of an abstract class:

/// C#
using System;
namespace DotNetTreats.OOSE.OOPSamples
{
public abstract class Shape
{
private float _area;
private System.Drawing.Color _color;
private float _perimeter;
public float Area
{
get
{
return _area;
}
set
{
_area = value;
}
}
public System.Drawing.Color Color
{
get
{
return _color;
}
set
{
_color = value;
}
}
public float Perimeter
{
get
{
return _perimeter;
}
set
{
_perimeter = value;
}
}
public abstract void CalculateArea();
public abstract void CalculatePerimeter();
}
}

Listing 1. The Shape abstract class in C#.

Polymorphism

Polymorphism allows objects to be represented in multiple forms. Even though classes are derived or
inherited from the same parent class, each derived class will have its own behavior. Polymorphism is
a concept linked to inheritance and assures that derived classes have the same functions even
though each derived class performs different operations.

Figure 2 shows a Rectangle, a Circle, and Square. All of them are shapes and as shapes their area
and perimeter can be calculated; however, each shape calculates its area in a specialized way.
Declaring a member as abstract allows polymorphism. The Shape class defines the CalculateArea()
and CalculatePerimeter() methods as abstract, this allows each derived class to override the
implementation of the parent's methods.

To following sample code shows an implementation of a derived class (rectangle). The specific
CalculateArea() and CalculatePerimeter() methods for the rectangle class illustrate polymorphism:

/// C#
using System;
namespace DotNetTreats.OOSE.OOPSamples
{
class Rectangle : Shape
{
private float _height;
private float _width;
public rectangle(float height, float width)
{
_height = height;
_width = width;
}
public float Height
{
get
{
return _height;
}
set
{
_height = value;
}
}
public float Width
{
get
{
return _width;
}
set
{
_width = value;
}
}
public override void CalculateArea()
{
this.Area = _height * _width;
}
public override void CalculatePerimeter()
{
this.Perimeter = (_height * 2) + (_width * 2);
}
}
}

Listing 2. Polymorphism represented in the Rectangle's methods.

Virtual keyword

The virtual keyword allows polymorphism too. A virtual property or method has an implementation in
the base class, and can be overriden in the derived classes.

To create a virtual member in C#, use the virtual keyword:

public virtual void Draw()

To create a virtual member in VB.NET, use the Overridable keyword:

Public Overridable Function Draw()

Override keyword
Overriding is the action of modifying or replacing the implementation of the parent class with a new
one. Parent classes with virtual or abstract members allow derived classes to override them.

To override a member in C#, use the override keyword:

public override void CalculateArea()

To override a member in VB.NET, use the Overrides keyword:

Public Overrides Function CalculateArea()

Conclusion

Inheritance allows developers to manage a generalization and specialization relationship between


objects. OOP concepts such as abstraction and polymorphism help to define better object models
where object hierarchies are designed with reusability in mind. In this article, I examined the concept
of inheritance, abstraction, and polymorphism. The third and last part of this series will examine the
concepts of interface, multiple interface inheritance, collections, and overloading.

Note: The sample source code* for this article works only in Visual Studio 2005.
Abstract Classes and Class Members

Classes can be declared as abstract by putting the keyword abstract before the class definition. For example:

C#

public abstract class A


{
// Class members here.
}

An abstract class cannot be instantiated. The purpose of an abstract class is to provide a common definition of a
base class that multiple derived classes can share. For example, a class library may define an abstract class that
is used as a parameter to many of its functions, and require programmers using that library to provide their own
implementation of the class by creating a derived class.

Abstract classes may also define abstract methods. This is accomplished by adding the keyword abstract before
the return type of the method. For example:

C#

public abstract class A


{
public abstract void DoWork(int i);
}

Abstract methods have no implementation, so the method definition is followed by a semicolon instead of a
normal method block. Derived classes of the abstract class must implement all abstract methods. When an
abstract class inherits a virtual method from a base class, the abstract class can override the virtual method
with an abstract method. For example:

C#

// compile with: /target:library


public class D
{
public virtual void DoWork(int i)
{
// Original implementation.
}
}

public abstract class E : D


{
public abstract override void DoWork(int i);
}

public class F : E
{
public override void DoWork(int i)
{
// New implementation.
}
}

If a virtual method is declared abstract, it is still virtual to any class inheriting from the abstract class. A class
inheriting an abstract method cannot access the original implementation of the method—in the previous
example, DoWork on class F cannot call DoWork on class D. In this way, an abstract class can force derived
classes to provide new method implementations for virtual methods.

Sealed Classes and Class Members

Classes can be declared as sealed by putting the keyword sealed before the class definition. For example:

C#

public sealed class D


{
// Class members here.
}

A sealed class cannot be used as a base class. For this reason, it cannot also be an abstract class. Sealed
classes prevent derivation. Because they can never be used as a base class, some run-time optimizations can
make calling sealed class members slightly faster.

A class member, method, field, property, or event, on a derived class that is overriding a virtual member of the
base class can declare that member as sealed. This negates the virtual aspect of the member for any further
derived class. This is accomplished by putting the sealed keyword before the override keyword in the class
member declaration. For example:

C#

public class D : C
{
public sealed override void DoWork() { }
}

Anda mungkin juga menyukai