Polymorphism: Part 1

Note: I am teaching a course in Austin TX on Object Oriented Programming in March. I’ll also be speaking at the Austin .Net Users Group on this topic.

To say that understanding polymorphism is critical to understanding how to effectively utilize an object-oriented language is a bit of an understatement.  It’s not just a central concept, it’s the concept you need to understand in order to build anything of size and scope beyond the trivial.  Yet, as important as it is I feel it is often quickly glossed over in most computer science curriculums.  From my own experience, I took two courses that focused on OOP, undergraduate and graduate, but I don’t think I truly understood its importance until later.[1] [2]

In C#, there are actually two forms of polymorphism available; Subtype Polymorphism through inheritance, and Parametric Polymorphism through the use of Generics. Generics is an important concept and deserves it’s own discussion.   But we are going to focus on Subtype for now.

Polymorphism lets you have different behavior for sub types, while keeping a consistent contract.

Now that sentence hides a lot of nuances and potential.  What exactly does this do for you?

  • Reduces coupling in your application
  • Reduces complexity by separating logic into smaller, more manageable pieces
  •  Increases the flexibility of your application by letting you change behavior by creating new classes to handle new functionality

The Mechanics:

Let’s go through a real simple example, just to describe the mechanics of how to use this.  Don’t worry, we’ll take the training wheels off real fast.  There are three basic steps necessary at this point: 1) define the contract, 2) create concrete implementations, 3) leverage the abstraction.

Step 1: Define the Contract

You need to define the contract that will define abstraction the rest of your system will interact with. In C# you can use either an Interface or a Class.  The class can either be an abstract class or a concrete class.  The only different between a concrete class and an abstract class is that you can’t directly use the abstract class, only concrete classes that inherit from it.  You also cannot create an instance of an Interface either.  The difference between an Interface and an abstract class is that an interface can only define the contract; you cannot implement any of the fields on an interface.  With an abstract class however you can define a method and implement it, so that all subtypes inherit the same behavior.

We’re going to create a component the sends messages to users.  We’ll start with the contract.  In this case we’ll use an interface to define the contract.

public interface ISendMessages{
  void Send(Message msg)
}

It’s a very simple abstraction and only includes what we need it to do.  Now what we’ll do is create some concrete implorations of the interface.

public class EmailMessenger: ISendMessages{
  void Send(Message msg){
    //do all the work to send an email
  }
}

public class SMSMessenger : ISendMessages{
  void Send(Message msg){
    //do all of the stuff needed to do an sms message
  }
  

Now we’ve got two different behaviors with the same while keeping a consistent contract for send a message.  Now we’ll leverage the abstraction somewhere else in our application.

public class OrderProcessor{
  ISendMessages message_sender;
  public OrderProcessor(ISendMessages messenger){
    message_sender = messenger;
  }
  
  publc void ProcessOrder(){
    //do something the order
    
    //now send a message about the order
    var msg = CreateOrderMessage()
    message_sender.send(msg)
  }
}

Notice that the constructor takes a parameter of ISendMessages, not a concrete implementation.  The OrderSender is not concerned with determining what type of message should be sent or the implementation details of sending the message.  It only needs to know that the contract requires a Message object.   This is known as the Inversion of Control Principle.  By using only the abstraction and not the concrete types in the OrderProcessor the OrderProcessor has inverted control of how to send the message to the originator.  When the OrderProcessor is created, it must be told what implementation to use.

Also notice that because the contract in both concrete implementations, we can substitute any subtype for the base type (in this case the interface).  This is another of the design principle: Liskov Substitution Principle.  Let’s change the implementation a bit that will break LSP.

public class SMSMessenger : ISendMessages{
 public string Carrier {get;set;}
 void Send(Message msg){
    //send the msg
  }
}
public class OrderProcessor{
  ISendMessages message_sender;
  public OrderProcessor(ISendMessages messenger){
    message_sender = messenger;
  }
  
  publc void ProcessOrder(){
    //do something the order
    
    //now send a message about the order
    var msg = CreateOrderMessage()
    if(message_sender is SMSMessager){
      message_sender.Carrier = "carrier";
    }
      message_sender.Send(msg);
  }
}

Now that we need to set the Carrier on the SMSMessenger, we have to change what the order processor to set the carrier in the case of SMSMessager.  As you can see it really complicates using the messenger.  Now the OrderProcessor must have specific knowledge on how use a concrete type, and so will every other component that needs to send a message.  In this case there are several ways to solve this problem will still maintaining the LSP and we’ll discuss some of them later.


[1] To be fair I took the graduate level course after a couple of years of experience, but I felt that I had a better grasp of the material than my professor did.

[2] While I don’t think I learned much about OOP in graduate school, I learned a lot of other things that would never have been exposed too otherwise and overall I think the experience is worthwhile.

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://pulse.yahoo.com/_RBXXUPWX5RVG3L5BXU22RBZ3G4 Oded

    Surely you mean nuances and not nuisances in the sentence just after the definition of polymorphism? 

    • John Teague

      Hah, thanks

  • Peter Stegnar

    .

    • John Teague

      fixed it. thanks.

  • Peter Stegnar

    “Let’s change the implementation a bit that will break LSP.” You are missing a change in a SMSMessenger class here. “Carrier ” property is missing.

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1301

  • Ptran123

    Hi John, I think what you are describing as Inversion of Control is, in fact, Dependency Inversion.

    • John Teague

      Yeah, that’s true. I guess I’ve use the terms interchangeably, thought I’m sure there is some small difference in their meaning.

  • Paul Marfleet

    Small correction – it’s the Liskov Substitution Principle, named after Barbara Liskov.

  • http://www.facebook.com/profile.php?id=10728177 Jimmy Carter

    Hi, I’m trying to follow your article, but having some trouble. In some places, for example here:  ”Notice that the constructor takes a parameter of ISendMessages…”, it seems like I should be looking at example code, but I don’t see an example to take notice of … would you consider some code snippets? Thanks!

    • http://www.facebook.com/profile.php?id=10728177 Jimmy Carter

      thanks!

    • John Teague

      Hey Jimmy,
      There are code snippets as embedded gist files. Perhaps your RSS reader is not rendering them. You might try going directly to the site if you can’t see them.

      • John Teague

        Actually I just visited the site and they did not appear.  I refreshed the page and the did.  Must be a wp thing.

  • Pingback: The Daily Six Pack: February 25, 2013 | Dirk Strauss

  • JohnoTickens

    If you’re teaching C# I recommend you learn the C# style guidelines. Your code looks like Java. Your naming is a bit dodgy too. ISendMessages would be better named IMessageSender, as that is how you named your field. Don’t teach bad habits. 

    • John Teague

      Actually, this is the new style that is gaining popularity. The “I” i the name is Not used to as Hungarian notation to mark an interface, but instead used as pronoun “I” and the rest of interface name describes the behavior. This is my naming style. Understandable if you don’t like it, but I wouldn’t call it a bad habit.

      • Larry

        I think JohnoTickens’ point is that the name of an Interface should be a noun and not an action phrase. So, IMessageSender (or MessageSender if you choose) would be more appropriate because objects will be instantiated from its subtypes. This is likewise to Classes being named as nouns but not verbs but most seasoned OOP developers.

        • John Teague

          I’ll repond to this one more time, then I’m going to let this conversation die.  This is a naming style for interfaces that describes the behavior of what the interface does, intentially using verbs in the name.  The intent of this naming style is “I do this”.  Not “Interface For Something”. I’m intentionally using verbs in my interface names.  NServiceBus is an example of where this is used.

          I don’t want to get into any religious naming wars here.  So if you do not prefer this particular style let’s agree to disagree.

          • Nathan Alden

            Your intent is misplaced and contradicts decades of usage patterns. Additionally, it’s factually wrong. An interface does nothing. It merely represents that which does something.

        • Simon

          Udi Dahan calls these Role Specific Interfaces. If you’d like to get up to speed on the concept here’s a good video on it: http://www.infoq.com/presentations/Making-Roles-Explicit-Udi-Dahan

          • John Teague

            I am familiar with Udi’s Role Specific, especially after I attended histraining course. This is something different.

            I named it the way I wanted. It’s just a different style of naming interfaces.  It is intentional. If you don’t like it fine.  I’ll be happy to continue this conversation on twitter, skype or email, but it’s really not important to the concepts I’m tring to get across.

          • Matthew Roberts

            John, its an interesting POV. I personally am not used to this way mainly because the .NET community are well attuned to using singular nouns for object naming (following Microsoft best practises of course!). 
            I recently started learning Objective-C and was surprised to see many objects names were verbs.

            But at the end of the day, the compiler wont argue with you – only us humans will =]

          • Matthew Roberts

            John, its an interesting POV. I personally am not used to this way mainly because the .NET community are well attuned to using singular nouns for object naming (following Microsoft best practises of course!). 

            I recently started learning Objective-C and was surprised to see many objects names were verbs.

            But at the end of the day, the compiler wont argue with you – only us humans will =]

    • John Teague

      Actually I just visited the site and they did not appear.  I refreshed the page and the did.  Must be a wp thing.

  • Grammarcop

    its (possessive)
    it’s (it is)

  • Julien Nitard

    I guess that it is bad form to call interface polymorphism “inheritance”. That’s true in C++ where you can’t actually distinguish interfaces from abstract base classes, but in C#, Java and Go they are entirely different.

    So, in total, there are at least 4 different forms of polymorphim in C#:
     - Inheritance
     - Interfaces
     - Generics
     - Dynamics

    Some people also choose to categorize function overloading under polymorphism, though not everybody agrees.

    • John Teague

      That may be true.  But I was keeping with my definition of polymorphism, I think it’s okay.  We’re going to to see some more “true inheritance” examples later.  Also, because I don’t build big inheritance models most of my code looks like this so it’s easier for me to come up with examples.  I agree my examples are not the best.

  • Crowcoder

    Good stuff, but you really need to proofread.

    • John Teague

      I agree. I’ll try to do better in future posts.

  • Henry R

    OrderSender? Do you mean OrderProcessor? ;)

  • Henry R

    By the way, I like your article about OOP, it’s short but concise.

  • Dan Sutton

    I have a feeling that in reality you wouldn’t use an Interface here; you’d use an Abstract Class — if you were actually to write something like this, you’d find that a message sender would end up having a bunch of common properties and methods despite having to send messages to disparate destinations (strip HTML tags out of text; check validity of destination address structure, etc.) which would be best shared inside an abstract superclass. When doing object-oriented design, it’s bad practice to assume an interface before an abstract superclass, since doing so encourages you not to think in terms of assimilating common code into one place.

    • John Teague

      Yes, you might have some common logic that all Message Senders do, I’m going to show an example how how you can manage that in part 3.

      But I would not start with an Abstract Class, I would continue using the interface _until_ you have some shared logic between the implementations.  Keeping with the interface keeps you focused on the behavior you need not the implementation of the behavior. 

      Once you’ve established you need an abstract class, it’s simple matter of having the abstract class implement the interface and then change your concrete implementations to inherit from your base class.  That way none of the components dependent on the messengers will need to change.

  • Johnturner

    and why is the msg sent twice?

    • John Teague

      Oops, sorry about that.  It’s not like I actually executed this code ;)

  • ChadF

    message_sender.Carrier = “carrier”;Not to mention _if_ the message sender is shared in a multi-threaded environment.. while Send() can be [implemented as] an effectively atomic action, the carrier set and then send call race condition could have issues. While technically synchronization would be the subject of a completely different article, the threaded expectations (or irrelevance of) is a subtle part of the OOP contract, in practice.

    • John Teague

      If synchronization is a concern, you could wrap it in a lock statement.  However, I’m trying to keep the examples free of extraneous concerns to illustrate the concept. 

  • rmarchet

    Great article. Thanks!

    I’m not trying to be critical here, but I’m having trouble understanding your use of “OrderSender” in your discussion under the gist block w/ orderprocessor and processorder. The term doesn’t show up in any of the code (shown). 

    I know your busy updating as we speak.  So, thanks; and thanks for giving back../rm.

    • John Teague

      That was a typo on my part, it should have been OrderProcessor to be consistent with the examples

  • Nathan Alden

    ISendMessages? No you don’t. You’re an interface; you represent that which sends messages. IMessageSender is much more accurate. Please, let’s all stop trying to make C# (and other similar languages) read like English; it’s infantile.

  • Carlos Ribas

    NServiceBus is full of self-contradictions with regards to this “new style” interface naming.  IHandleMessages simply aliases the traditionally-named IMessageHandler.   There’s ISpecifyMessageHandlerOrdering and then there’s IMessageCreator (not ICreateMessages?).  

    This strikes me as ridiculous.  If programming were a democracy I’d vote for the “let’s stop with the cute English-y stuff” party.

  • Dbr

    Hi. Sorry if this is a little basic, but can you just quickly define “polymorphism” as opposed to “inheritance”?  I see the benefit of the way you have written your code, I don’t need help with that, but I would just call that a good example of inheriting from an interface?  What is it about it that makes it inheritance?

    • Dbr

      Typo – I meant to say  “What is it about it that makes it polymorphism?”…

    • John Teague

      My development style is more composition than inheritance, so it was just easier for me to make the examples like this.  the ISendMessages interface could have easily been an abstract class (I’m hoping to get to an example where it has one).  Then the inheritance tree would start from a class.  To me however, if you look at how I defined polymorphism, where you have different behavior with a consistent keeping a consistent contract, it doesn’t matter if you start from a base class or an interface.

      The important part is to use the abstraction, not the concrete implementation.  Whether the abstraction is an interface or class you get the same benefits.

      HTH,
      John

  • Pingback: Reading Notes 2013-03-04 | Matricis

  • Mario Pareja

    Now that everyone is hopefully done commenting on your “IWhatever” naming style, I’d like to ask a simple question. What were some of those other things you felt you _did_ learn that you wouldn’t otherwise be exposed to?