Abstract classes and Interfaces are very different, and cannot be substituted.
We use Abstract classes to provide a common base for concrete classes - which doesn't mean a lot, but think of it like cars.
All cars are members of the Abstract class Car - they share common properties and methods, in that you can learn to drive a Car, and apply that to any derived class instance.
But you can't drive a Car - you drive "this car" or "that car", "your car" or "my car" - which are instances of a Car, but more importantly, "MyCar" is a specific instance of a make and model: "Mercedes"."A Class", while "YourCar" is a specific instance of "Ford"."Feista"
The Model "A Class" is a class, derived from "Mercedes", which is derived from "Car". "Car " is abstract, as is "Mercedes" and "Ford", but the actual models are concrete: "A Class", "Fiesta". The Car class provides the basics of the "Drive" method, but "Mercedes" refines that to which garage you need to visit to buy one - it adds a "Dealership" property collection. "A Class" refines "Mercedes" further by saying "it's this long, this wide, has one of these engines" and so on.
You can't buy "a Mercedes" - it's an abstract concept - but you can buy "an A Class" because that specifies what options are available as a Car instance.
But they are all Cars!
While you can do that with non-abstract classes just using inheritance, a concrete Car class means that you could do this:
Car myCar = new Car();
And what exactly do you get in "myCar"? What parts does it need? What fuel does it use? What size are it's tires? Because it's "a car" you don't have any information on that, or anywhere to store it.
Interfaces are different: they aren't classes at all - they are a contract. You can't have any code at all in an interface (unlike an abstract class where you can) but you must implement every method, property, event, and delegate that is defined in the Interface. If you don't, you get an error. If you do, then you get the advantages of "being in the club" that the Interface contract allows you into.
For example, look at the IEnumerable Interface - adding that to any class (and implementing the methods) allows your class to be used directly in a
loop. Only those that implement the IEnumerable contract can be used with
, but everything that does can be - regardless of the base class they are derived from. And since you can only derives from a single class (no multiple inheritance in C#!) the absence of Interfaces would limit what you could do with IEnumerable considerably.