C# is a typical object oriented language in that it has classes, abstract classes, and interfaces. Before you can even start to design a class hierarchy, you must first understand what distinguishes interfaces, abstract classes, and classes.
Interfaces represent a contract. Any class, interface, or abstract class that implements an interface agrees to that contract. Meaning that anything in that interface must be publicly implemented. Essentially, an interface represents a public facing contract. An interface that implements another interface does not have implement that interface's contract. The possibility exists that a long chain of interfaces could be created. Any class or abstract class that implements an interface in that chain must implement all of the contract elements in the interface chain starting at the point of implementation and moving backward to end of the chain. Given a long enough chain, this could become confusing and perhaps frustrating, but that's another topic for another post. Anyway, an interface represents a contract, but what does that mean in grander scheme of a design?
An interface contract represents the policy of the system. For every policy you should have interface. This how you achieve a separation of policy and mechanism. That separation allows for the mechanism to change while not having to change very much of those who interact with the policy. What about abstract classes? How are they different from interfaces?
Abstract classes can contain actual implementations. Those implementations can do nothing if that's appropriate. Why? An abstract class is not a fully realized class. It cannot be instantiated. If an abstract class can contain implementations but cannot be instantiated, then what good is it?
Abstract classes represent generic objects. They contain implementations common across an entire group of classes. If an interface is a policy, then an abstract class is is a common mechanism. This allows classes to only focus on the mechanism specific to its needs. More common needs an be "abstracted." This is allows hierarchy designers to focus change into more focuses areas as generic classes are less likely to change than specific ones. Finally, what are classes good for if we have interfaces and abstract classes?
Abstract classes cannot be instantiated so you could not build software from, but, more importantly, classes represent the actual objects inside of your system. This is where the contracts and generics are finally realized into usable components. All of the other components build up to classes. They are the culmination of your design.