Implementation inheritance models an "IS A KIND OF" relationship, whilst interface inheritance models a "CAN BEHAVE LIKE" relationship. It's no coincidence that many of the BCL interface names end with "-able", representing the ability to do something. To demonstrate, image the following code:
class Person
{
public string Name{get;set;}
public void Walk() {/*code elided*/}
}
class Employee : Person
{
public int Id{get;private set;}
}
Clearly, an Employee "is a kind of" Person. All employees are people, therefore they all have a Name and can Walk(). By all means make Person or Employee abstract, it doesn't change the fact that all employees are people.
Now let's get a bit more abstract and talk about the concept of being a vehicle. The absolute essential for a thing to be a vehicle is that it must be able to move and stop. You might include steering and carrying passengers but I'm keeping it very abstract.
Let's think about some things that are vehicles. A car, of course, but how about a person? They can move and stop (and when I give my nephews and nieces piggy-backs I'm carrying passengers too!) A wheely chair? I'm forever davrossing around the office. I'm a keen sailor too, and use the wind to accelerate and decelerate my vehicle.
You can't model this kind of a relationship using implementation inheritance, because you have lots of different things that "can act like" a vehicle but don't neccessarily inherit from the same base class.
A pogostick (with apologies to professional pogo-ers) IS A KIND OF Toy, but CAN ACT AS a vehicle. Not all toys are vehicles. A Person has no relationship to a Car, other than the fact that it CAN ACT AS a vehicle.
interface IVehicle
{
void Move();
void Stop();
}
class Toy{}
class PogoStick : Toy, IVehicle
{
public void Move(){ /* boing boing */}
public void Stop(){ /* fall over */}
}
class Car: IVehicle
{
public void Move(){ /* vroom vroom */}
public void Stop(){ /* <screeeech!> */}
}
class Person : IVehicle
{
public string Name{get;set;}
public void Walk() {/*code elided*/}
void IVehicle.Move() { Walk(); }
void IVehicle.Stop() { /*whatever!*/}
}
class Program
{
static void Main()
{
IVehicle[] vehicles = new IVehicle[3];
vehicles[0] = new PogoStick();
vehicles[1] = new Car();
vehicles[2] = new Employee(); //implements IVehicle because it IS A KIND OF Person
vehicles.ForEach(v => v.Move());
//it's worth pointing out that
vehicles[2].Stop();
//works fine, but
Person p = new Person();
p.Move();
//won't, as I explicitly implemented the interface, meaning I can only get at the
//methods via a reference to the interface, not to the implementing class.
}
}
To use an example from .NET itself, what on Earth does a string have in common with a List? Not a lot, except that I can "foreach" both of them:
class Demo
{
static void Main()
{
string s = "Hello!";
List<Employee> payroll = new List<Employee>();
for each (var item in s)
{
Console.WriteLine(item);
}
for each (var item in payroll)
{
Console.WriteLine(item);
}
}
The common base class for string and List is object, but not all objects are "for-each-able", so there has to be something else going on. Namely that they both implement the IEnumerable interface (there's that -able!)