This post is for beginners.
Many beginners struggle with the concept of an Interface. Over on the ASP.NET forums, where I moderate, the question is asked a surprising number of times. I'm going to try to describe and explain the concept of an Interface…simply and concisely.
Let's say we are going to program a game and the game needs a random number generator.
We want to try different random number generators because all random number generators are not created equal. To make it easy to switch number generators, we will use an Interface.
The Interface
So, here is the (simple as possible) Interface for our Random Number Generator:
public interface IRandomNumberGen
{
int GetNextNumber();
}
Notes
The public keyword is not needed (or even allowed) on the GetNextNumber()
method. An interface declares access methods so by default they must be public
. A private
method in an interface makes no sense...and causes an error.
An Interface cannot contain fields. Doing so causes an error.
Hmmm, it seems an Interface is a collection of empty functions that are implicitly public.
Derive some Classes from the Interface
Here are two Random Number Generators each inheriting from our Interface.
class RandomNumberCoinFlip : IRandomNumberGen
{
public int GetNextNumber()
{
return 1;
}
private String CoinType;
}
class RandomNumberOuija : IRandomNumberGen
{
public int GetNextNumber()
{
return 2;
}
}
Notes
Both classes implement the GetNextNumber()
function. One class has an additional field…but that's OK; it doesn't matter:
As long as a class implements the functions in the Interface, it can do anything else it pleases. But a class derived from an Interface must implement the functions in the Interface.
So big deal, what have we accomplished?
Here are the Classes in Use
protected void Button1_Click(object sender, EventArgs e)
{
IRandomNumberGen Generator;
Generator = new RandomNumberCoinFlip();
Response.Write(Generator.GetNextNumber() + "<br />");
Generator = new RandomNumberOuija();
Response.Write(Generator.GetNextNumber() + "<br />");
}
Notes
The Generator reference can be assigned to any object created from a class derived from the IRandomNumberGen
Interface and it can call the GetNextNumber()
method. It doesn't know or care about any part of the class except the methods it expects to be there.
Here’s Another Usage Example
public void MakeAMove(IRandomNumberGen NumberGenerator)
{
int Number = NumberGenerator.GetNextNumber();
}
protected void Button1_Click(object sender, EventArgs e)
{
MakeAMove(new RandomNumberCoinFlip());
MakeAMove(new RandomNumberOuija());
}
Notes
This shows a function that takes an Interface as a parameter. Any object derived from the Interface can be passed to the function.
That's cool but the same thing could be accomplished with an abstract
base class and virtual functions. So what's the deal with Interfaces?
Multiple-Inheritance is not Supported in .NET… Except for Interfaces!
Here is one more class that implements the Interface. In addition to IRandomNumberGen
, it implements IDisposable
.
class RandomNumberDeckOfCards : IRandomNumberGen, IDisposable
{
public int GetNextNumber()
{
return 3;
}
public void Dispose()
{
}
}
And here it is being used:
protected void Button1_Click(object sender, EventArgs e)
{
IRandomNumberGen Generator;
Generator = new RandomNumberDeckOfCards();
Response.Write(Generator.GetNextNumber() + "<br />");
IDisposable Disposer = Generator as IDisposable;
Disposer.Dispose();
}
Notes
As before, an IRandomNumberGen
reference can be assigned to the object and the GetNextNumber()
method called.
In addition, an IDisposable
reference can be assigned (with a cast) to the object since it implements IDisposable
and the Dispose()
method can be called.
In the above code, the two Interface references, Generator
and Disposer
, both point to the same object. They have different 'views' of the same object. And that, is the deal with interfaces.
Finale
I know there are thousands of articles around explaining this concept which is odd because once understood, the concept is trivial. But sometimes one explanation "fits the brain" better than another explanation. I hope this explanation fits someone's brain.
Update
Many have asked for clarification between abstract
classes and interfaces. In addition to "multiple inheritance" which abstract
classes do not support, there is another key difference: Interface classes may NOT contain fields. If you need fields or properties in the base class, you cannot use interfaces.
Update 2
Strike part of the last update. You can have properties in an interface but not fields. Thanks to Wallism for pointing this out.
public interface MyInterface
{
int LastResult { get; set; }
}
public class MyClass : MyInterface
{
public int LastResult { get; set; }
}
Steve Wellens