Problem
I made this small program to demonstrate to myself an example of interface. I wanted to confirm whether it is correct and if there is anything more I should know about interfaces other than the importance of implementing polymorphism and multiple inheritance.
//program.cs
class Program
{
static void Main(string[] args)
{
Dog oDog = new Dog();
Console.WriteLine(oDog.Cry());
Cat oCat = new Cat();
Console.WriteLine(oCat.Cry());
Console.ReadKey();
}
//IAnimal.cs
interface IAnimal
{
string Cry();
}
//Dog.cs
class Dog : IAnimal
{
public string Cry()
{
return "Woof!";
}
}
//Cat.cs
class Cat : IAnimal
{
public string Cry()
{
return "Meow!";
}
}
Solution
Your example accesses the cat through a variable of type Cat
and the dog through Dog
. This would work, even if both classes did not implement a common interface. Inheritance is not involved.
In order to really demonstrate the usefulness of polymorphism I suggest the following code:
interface IAnimal
{
string Name { get; set; }
string Cry();
}
class Dog : IAnimal
{
public string Name { get; set; }
public string Cry()
{
return "Woof!";
}
}
class Cat : IAnimal
{
public string Name { get; set; }
public string Cry()
{
return "Meow!";
}
}
And here is a possible test:
static void Main(string[] args)
{
var animals = new List<IAnimal>();
animals.Add(new Dog { Name = "Robby" });
animals.Add(new Dog { Name = "Fify" });
animals.Add(new Cat { Name = "Mimy" });
PrintAnimals(animals);
Console.ReadKey();
}
private static void PrintAnimals(IEnumerable<IAnimal> animals)
{
foreach (IAnimal animal in animals) {
Console.WriteLine("Here is {0}: {1}", animal.Name, animal.Cry());
}
}
It demonstrates that different types of animals can be treated the same way, but behave differently. This is what polymorphism is about. The word means many (poly) shapes or forms (morph). You can add different types of animals to a collection.
The PrintAnimals
method has a parameter of type IEnumerable<IAnimal>
allowing you to pass it different types of collections (arrays, lists, linked lists, stacks and many more, as yet another example of polymorphism). It uses a unique Console.WriteLine
statement for all types of animals, without even knowing of which type an animal really is. The only thing it knows is, that it implements IAnimal
. You could even add new types of animals later, without having to change the PrintAnimals
method and it would still work as expected.
Your code is quite simple and works, there is not much to review.
Few points:
- You shouldn’t use variable names like
oDog
. If theo
is meant to indicate that it’s an object, then that information already contained in the type of the variable, so the prefix is useless. If it indicates something else, then it’s very confusing. - Your code is not a very good example, because it would work exactly the same even without the interface.
An interface is like a contract. In you case – all clases that inherits from IAnimal
must have a Cry()
method… (which is really mean 🙂 )
In in you example you are not really using the interface. try writing it like this:
IAnimal animal1 = new Dog();
Console.WriteLine(animal1.Cry());
IAnimal animal2 = new Cat();
Console.WriteLine(animal2.Cry());
And see that it still works.
Now try adding a method to your Cat
class. Perhaps an Eat()
method.
class Cat : IAnimal {
public string Cry()
{
return "Meow!";
}
public string Eat()
{
return "Meow i'm so full - mice is my favorite!";
} }
And then try calling that method with animal2
instance. You will notes you can’t!
animal2.Eat(); //<-- compile time error
Because we are now using animal2
only as IAnimal
. And all we know about an IAnimal
is that it can Cry()
A better exercise/code snippet to demonstrate the usefulness of an interface would be something like:
static void PrintAnimal(IAnimal animal)
{
Console.WriteLine(animal.Cry());
}
static void Main(string[] args)
{
IAnimal dog = new Dog();
IAnimal cat = new Cat();
PrintAnimal(dog);
PrintAnimal(cat);
Console.ReadKey();
}
The client expecting the interface (IAnimal
) only cares about that interface and not the specific implementation (Dog
, Cat
, etc). Therefore you could have the PrintAnimal
method (maybe class at some point) handle any kind of animal you may happen to want in the future. Your example would work whether you had an interface or not.