Click here to Skip to main content
Click here to Skip to main content

Extending Polymorphism Backward in Class Hierarchy

, 19 Jun 2009
Rate this:
Please Sign up or sign in to vote.
This article explains how to apply polymorphic behavior back in the class hierarchy

Introduction

This article explains how to apply polymorphic behavior backward in the class hierarchy.

Using the Code

This article uses Visual Studio 2008.

The Problem

You may want to apply polymorphic behaviour to the classes of different levels of the inheritance hierarchy that do not have a common interface. For example, imagine that you have an array of objects of different types inherited from the same base class. You'd like to call a method for all the objects in the array, but the method only exists in one of the inherited classes.

The most reasonable thing would be to move the method up in the hierarchy (and make it virtual, if needed). However, it is not always in your hands - the base class can be in a third-party library, or inaccessible due to other reasons.

The Solution

Using an extension method will allow you to do the trick. Here is the example.

Create a base class called Animal. Assume it is the class that is out of your reach, and you cannot modify it.

public abstract class Animal
{
}

Create an inherited class DomesticAnimal that introduces the method Says(). This is the method you'd like to call across all the classes inherited from Animal.

public class DomesticAnimal : Animal
{
	public virtual string Says()
	{
		return null;
	}
}

Create classes Cat and Dog that inherit from DomesticAnimal and implement the method Says().

public class Cat : DomesticAnimal
{
	public override string Says()
	{
		return "Meow!";
	}
}

public class Dog : DomesticAnimal
{
	public override string Says()
	{
		return "Woof!";
	}
}

Create a class Wolf that inherits directly from Animal and thus does not have the Says() method.

public class Wolf: Animal
{
}

Now imagine a client code that creates an array of the above Animal objects and wants to call Says() method on each object in the array, including Wolf.

static void Main(string[] args)
{
	Animal[] animals = new Animal[3];
	animals[0] = new Cat();
	animals[1] = new Dog();
	animals[2] = new Wolf();

	foreach (Animal animal in animals)
	{
		Console.WriteLine("{0} says {1}", 
			animal.GetType().Name, animal.Says());
	}
}

Of course this code would not compile. The following error will show up, pointing to the Animal.Says() method:

'BackwardPolymorphism.Animal' does not contain a definition for 'Says' 
and no extension method 'Says' accepting a first argument of type 
'BackwardPolymorphism.Animal' could be found 
(are you missing a using directive or an assembly reference?)

Let's now add a new static class that will provide an extension method Says() for Animal class (note the same name of the extension and inherited methods). We have to check object type dynamically and cast the object in order to call the intrinsic Says() method of the inherited classes.

public static class AnimalExtension
{
	public static string Says(this Animal animal)
	{
		string says = "[Unknown]";

		if (animal is DomesticAnimal)
		{
			says = ((DomesticAnimal)animal).Says();
		}

		return says;
	}
}

Now the code will compile. When running, it produces the following output:

BackwardPolymorphism_src

History

  • 19th June, 2009: Initial version

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

No Biography provided

Comments and Discussions

 
Question[My vote of 2] Extending Polymorphism Backward? PinmemberDarchangel23-Jun-09 4:39 
AnswerRe: [My vote of 2] Extending Polymorphism Backward? PinmemberStas Kashepava23-Jun-09 11:40 
Well, maybe you right in terms of name of the article is a bit confusing or ambiguous.
I meant to say that the example simulates polymorphic behavior rather than actually "alters polymorphism".
This example is closer to Mixins[^].
It appears that there is a discussion on whether mixins can be called polymorphism: see CategoryPolymorphism section[^].
And here are couple of C# mixin examples:
one[^]
two[^]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 19 Jun 2009
Article Copyright 2009 by Stas Kashepava
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid