The two concepts are different, but related.
Let's start with an Interface.
C# will only allow you to derive a new class form a single class:
public class MyBaseClass {}
public class MyDerivedClass : MyBaseClass {}
You cannot derive a class from two or more concrete classes:
public class MyBaseClass1 {}
public class MyBaseClass2 {}
public class MyDerivedClass : MyBaseClass1, MyBaseClass2 {}
So how do you add a grouping so that you can treat a class as a member of a club? For example, how do you say "this new class is based on a Control, but it also knows how to act like a List of items"?
The answer is to use an Interface. This lays out the rules of the "Club" (it defines which properties and methods you must implement in order to join) and does not in any way provide an code at all to either help or hinder you. In the example above, the IEnumerable Interface requires that you implement the
GetEnumerator
method, and when you do allows you all the priveliges ofthe club membership - for example, your class can now appear in a foreach loop.
MyClass mc = new MyClass();
foreach (string s in mc)
{
}
}
public class MyClass : IEnumerable<string>
{
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
An abstract class is similar in a way, but it is a class in itself so you can derive from it, but you can't derive from any other class at the same time. It can implement properties and methods in the same way as a "normal" class, but it doesn't have to. The big difference between an abstract class and a "normal" (or concrete) class is that you cannot under any circumstances create an instance of the abstract class - you can declare a reference variable, but you can only ever create instances of derived classes.
For example, you could have an abstract class "Fruit" which is the base for the "Apple", "Pear", and "Orange" classes.
Fruit f = new Apple();
Orange o = new Orange();
f = o;
Are all legal.
But you can't say:
Apple a = new Apple();
Orange o = new Orange();
o = a;
Because they are both Fruit, but they aren't the same fruit.
You use an abstract class to create a class that has no instances - but groups together instances, and allows you to pass any of the instance classes through to a method which expects the abstract base class.
In the real world, you could define an abstract class "OutputDevice" which says it wants a Write method which takes a string, and define a FileOutputDevice and a TextBoxOutputDevice which are derived from the abstract. Provided both concrete classes implement the Write method, you can write a single method which takes an OutputDevice as teh parameter and prints the contents of a book to it. It will the=n work without changes to the code. And you could add a ConsoleOutputDevice class and the method still needs no changes to work!