Polymorphism

So Polymorphism in Wikipedia is defined here: http://en.wikipedia.org/wiki/Polymorphism_(computer_science)

In programming languages and type theory, polymorphism is the provision of a single interface to entities of different types. A polymorphic type is a type whose operations can also be applied to values of some other type, or types.

Got that? No, me either. Let's try describing the concept in more every day terms.

Polymorphism is the term used to describe the fact that an object can be identified in multiple different ways. We use this same principle in everyday life. For example, take a look at the image below.

Deans 1967 Chevrolet Impala

The car can be identified in many different ways, ask a dozen people to describe the car and you would get a dozen different answers.

  • A black car
  • An American car
  • A Chevy / Chevrolet
  • An Impala
  • A gasoline / petrol car
  • A vehicle
  • Transport
  • A 1967 Chevrolet Impala, Black

Some of those answers will be more specific descriptions of other answers. We could arrange those answers into a loose hierarchy.

  • A vehicle / Transport
    • Car
      • A black Car
      • An American Car
        • A Chevy / Chevrolet
          • An Impala
            • A 1967 Chevrolet Impala, Black
              • Deans car
      • A gasoline / petrol car

All of those terms are correct and accurate, some being more specific than others.

Now imagine that in an object oriented programming language we created a series of inherited classes that could be used to implement these descriptions.

Transport Hierarchy

So we have established that the vehicle in the image can be identified and described in varying different ways. When it comes to using these objects in an object oriented programming language, the same principle applies.

Let us assume that our code implements the following three methods:

decimal CalculateProfitabilityPerSeat(Transport transport)
decimal CalculateFuelEfficiency(CombustionVehicle combustionVehicle)
decimal CalculateInsurancePremium(CarInstance carInstance)

To perform the calculation, each method requires a different type of object. The calculation on profitability per seat needs to know the seating capacity, so the method requests a 'Transport' object. Like-wise, the other two methods are defined to require the type of object that they need to perform their calculation.

If our code has an instance of a 'CarModel', then because the 'CarModel' object inherits from both 'CombustionVehicle' and 'Transport', our instance is guaranteed to have the data that those object types offer. This means that our 'CarModel' can actually be passed straight into either of the first two methods above.

var carModel = GetCarModel(id);
var profitability = CalculateProfitabilityPerSeat(carModel);
var fuelEfficiency = CalculateFuelEfficiency(carModel);

No casting is required, or referencing the item as a new type. Because a CarInstance is also a CombustionVehicle and a Transport, we can simply pass it. THIS is polymorphism.

So there is one more factor to consider. Because our CarModel does not include the data for a CarInstance, we cannot pass it to the third method, the CalculateInsurancePremium. So Polymorphism only works in the direction of referring to an object in less specific terms, never in more specific terms.

That is Polymorphism in its most typical form, once the concept sits comfortably with you, it is worth further reading on the specific sub types of Polymorphism. Below are some external links that should be useful:

A great follow on topic from Polymorphism is the Liskov Substitution Principle, which again really isn't as scary as Wikipedia makes it sound. Article here: Liskov Substitution Principle