Published: 27 Apr 2007
By: Brian Mains

Polymorphism and encapsulation are two big words in OO development, and are also a fundamental concept of software development. This article will demystify these concepts by showing you some real world examples.


Polymorphism is a simple concept that you understand right now, as it is prevalent through life. You are a person, which person is a base type and you are a more specific representation of that type. There are many people that inherit that type, of which you are a concrete implementation of that type: you have your own beliefs, attributes, and qualities that go beyond just a general person. For instance, we all have a blood type, shoe size, arm length, and many other properties. But we each add our own implementation to the person interface.

You drive an automobile, which this type has properties like wheel size, engine size, gas tank size, and other properties. The automobile you drive is a concrete implementation of the automobile interface. It has additional features, like sliding doors, logo type, cd changer slot count, moon roof lever location, or other various properties that are specific to the make/model of the car. In addition, automobile may have certain behaviors like open/close door, open trunk, turn wheel, and other behaviors that would be specific to an automobile.

In OO programming, using the automobile example, Automobile would be the base class, and each automobile manufacturer would have its own implementation. For instance, Honda has V-Tec technology, which is in its own implementation. Volvo uses diesel engines, which is the TDI technology. More importantly, you may add an added level of detail between automobile and the make/model implementation, such as Car, Truck, or Suv supertypes, to provide more relevant information.

Let's take a look at the automobile scenario. Here is an example automobile class:

The Automobile class is the interface, in that it defines an interface that classes will derive from. You can't directly instantiate it through new Automobile() because it's not an implementation; however, you can cast derived types to the Automobile type. In this sense, it defines a common interface across many derived implementations.

It's important to note the BodyType property. This property is declared abstract, meaning that any derived implementation must override it and return some relevant string (we will see more of this with the next class definitions). This is similar to the Template Method pattern in that it exposes properties/methods that derived classes must override, but which Automobile doesn't need to know anything about. Automobile wants the derived class to return something relevant to it, but doesn't care what.

Now, from the example above, let's say we want a higher level of abstraction, in that there are varying types of cars and we want to target that. It is possible for classes to inherit from Automobile, but to also be an interface in that it can't be directly instantiated, but any class can inherit additional properties/methods from it. Below are two such class definitions, for Car and Suv.

Notice the BodyType method is overridden to return a string that represents the type of body that's appropriate to the supertype. Also notice that Car and Suv also expose their own properties/methods, even abstractly in terms of the Car.IsFast property. Lastly, let's create an implementation of the Car class:

The SubaruWrx class can use any of the properties defined in Automobile and Car. It has DoorCount, EngineType, etc. properties that are available, because it inherits from Car, which Car inherits from Automobile. You can cast SubaruWrx to Car or to Automobile, because it inherits from these base classes, and adds its own properties/methods. However, say you cast SubaruWrx to Automobile; none of the properties/methods defined in SubaruWrx or Car will be available, because all this object knows is that it's of type Automobile. To gain access to those properties/methods, you must upcast to the appropriate type.

There are several ways that polymorphism can take place. The first is through class inheritance, which you see above. Class inheritance exposes the interface of the base class to all of the derived classes. Another option is interface inheritance. The interface declares a contract that the class must follow to implement the interface. In addition to class inheritance, an object can inherit from one or more interfaces, which adds properties/methods to the body of the class that it must provide implementation for. This is another common option that can be used in .NET development. Some languages offer the ability to inherit from multiple base classes; however, .NET is not one of those languages.

Examples of Polymorphism

There are many examples of Polymorphism in the .NET framework. One of them is the Membership provider. When you call Membership.GetUser or any other method, it calls the default provider, which is defined as a MembershipProvider class. Any derivatives (SqlMembershipProvider or other custom providers) expose the MembershipProvider interface to create a concrete implementation. You can easily switch the underlying data store without having to change any code for the Membership object.

When you work with a typed dataset, the base objects for the tables/rows are inherited from DataTable and DataRow. These objects can be downcast to this base type. When downcast to this type, only the properties/methods defined in DataTable/DataRow can be used, eliminating the strong-typing that comes from a typed dataset.

The GridView and DetailsView web controls allow you to create custom fields, by creating a class that inherits from DataControlField. Because of this, you do not have to create your own custom GridView/DetailsView classes to expose new field types; you simply create a new field that inherits from DataControlField, and create a custom implementation by overriding the base class's ExtractValuesFromCell and InitializeCell methods.


Think of encapsulation as a black box; data is sent to a method, a lot of work goes on using the data, of which you don't know or care about. An output is returned to the caller. That is the process of encapsulation, or information hiding. Let's take a look at the following class:

From this class, we see a class that works with multi-line text, ensuring that the new line text is separated by line and retrieved by an index value. The constructor takes a string and parses the initial text. It also allows the adding and removing of lines. However, notice that the base object that stores the lines, the CollectionBase object, is never exposed. Only certain object properties are exposed, but the list isn't directly exposed. This is information hiding, in that we don't need to expose the source object for subscriber to use it, but the subscriber can only use the exposed methods/properties to interact with it.

Why is encapsulation important? Using the above example, it would be really easy to change the underlying source to use a database, XML file, text file, or another data store, without breaking any code that the developer may have created. If the class exposed the list directly, any code that used the list would have to change, replacing it with database code. That makes using this class much harder to maintain and more likely that someone would stay away from using the class. But with the implementation above, nothing is known about the source and so switching the underlying data source is much easier.

This concept is prevalent throughout the .NET framework and any object-oriented development project, as it is important to hide certain information to the consumer of an object, because it aids in maintenance, development, and general use of the object.


This article walks through two of the biggest subjects in OO development, polymorphism and encapsulation, providing real concrete examples that developers can use to create better software.


The definition of polymorphism and information hiding (encapsulation) can be found on wikipedia.

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Brian Mains

Brian Mains is an application developer consultant with Computer Aid Inc. He formerly worked with the Department of Public Welfare. In both places of business, he developed both windows and web applications, small and large, using the latest .NET technologies. In addition, he had spent many hou...

This author has published 73 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category

C# 4.0 Reflection Programming - Part 3
In the previous article, we used the reflection to obtain the information of an assembly, module, ty...
C# 4.0 Reflection Programming - Part 2
As introduced in the first article, the most typically-used tools associated with .NET reflection ar...
C# 4.0 Reflection Programming - Part 4
In this last article of this series, we will learn what to do with reflection. But before making the...
Understanding and Using Extension Methods
Extension methods were new to C# 3.0. They allow you to add a method to an existing type without hav...
Introduction to C# 3.0 features
C# 3.0 introduced some of very useful features built on top of 2.0. This article explains the usage,...

You might also be interested in the following related blog posts

You should NOT use ASP.NET MVC if. . . read more
So How Do You Set The Last-Modified Header? read more
Polymorphism and Encapsulation read more
New C# Tutorial Lesson read more
If programming were an RPG... read more
TechBookReport review of 'Programming .NET Components' read more


Subject Author Date
placeholder Confused Marius Koen 11/22/2009 10:05 AM
RE: Confused Marius Koen 11/22/2009 10:08 AM
placeholder RE: RE: Confused Sonu Kapoor 11/22/2009 1:17 PM
RE: RE: RE: Confused Brian Mains 11/22/2009 8:12 PM
placeholder Polymorphism Dummy Ahuja 11/23/2010 11:14 AM
Not an easy read. An Phu 4/3/2009 11:09 PM
placeholder RE: Not an easy read. Brian Mains 4/5/2009 10:20 PM

Please login to rate or to leave a comment.