However, as long as you trust that Liskov's Substitution Principle will be followed, then why would you not allow it to be overriden?
For example, because I want the skeleton implementation of an algorithm to be fixed, and only allow specific parts to be (re)defined by subclasses. This is widely known as the Template Method pattern (emphasis below by me):
The template method thus manages the larger picture of task semantics, and more refined implementation details of selection and sequence of methods. This larger picture calls abstract and non-abstract methods for the task at hand. The non-abstract methods are completely controlled by the template method but the abstract methods, implemented in subclasses, provide the pattern's expressive power and degree of freedom. Some or all of the abstract methods can be specialized in a subclass, allowing the writer of the subclass to provide particular behavior with minimal modifications to the larger semantics. The template method (which is non-abstract) remains unchanged in this pattern, ensuring that the subordinate non-abstract methods and abstract methods are called in the originally-intended sequence.
Update
Some concrete examples of projects I have been working on:
- communicating with a legacy mainframe system via various "screens". Each screen has a bunch of fields, of fixed name, position and length, containing specific data bits. A request fills up certain fields with specific data. A response returns data in one or more other fields. Each transaction follows the same basic logic, but the details are different on every screen. We used Template Method in several different projects to implement the fixed skeleton of the screen handling logic, while allowing subclasses to define the screen-specific details.
- exporting / importing configuration data in DB tables to/from Excel files. Again, the basic schema of processing an Excel file and inserting/updating DB records, or dumping the records to Excel is the same for each table, but the details of each table are different. So Template Method is a very obvious choice to eliminate code duplications and make the code easier to understand and maintain.
- Generating PDF documents. Each document has the same structure, but their content is different each time, depending on lots of factors. Again, Template Method makes it easy to separate the fixed skeleton of the generation algorithm from the case-specific, changeable details. In fact. it even applies on multiple levels here, as the document consists of several sections, each of which consists of zero or more fields. Template Method is applied on 3 distinct levels here.
In the first two cases, the original legacy implementation used Strategy, resulting in lots of duplicated code, which of course over the years grew subtle differences here and there, contained lots of duplicated or slightly different bugs, and was very difficult to maintain. Refactoring to Template Method (and some other enhancements, like using Java annotations) reduced code size by about 40-70%.
These are only the most recent examples which come to my mind. I could cite more cases from almost every project I have been working on so far.
In layman's terms:
Interfaces are for "can do/can be treated as" type of relationships.
Abstract ( as well as concrete ) classes are for "is a" kind of relationship.
Look at these examples:
class Bird extends Animal implements Flight;
class Plane extends Vehicle implements Flight, AccountableAsset;
class Mosquito extends Animal implements Flight;
class Horse extends Animal;
class RaceHorse extends Horse implements AccountableAsset;
class Pegasus extends Horse implements Flight;
Bird
, Mosquito
and Horse
are Animals
. They are related. They inherit common methods from Animal like eat(), metabolize() and reproduce()
. Maybe they override these methods, adding a little extra to them, but they take advantage of the default behavior implemented in Animal like metabolizeGlucose().
Plane
is not related to Bird
, Mosquito
or Horse
.
Flight
is implemented by dissimilar, unrelated classes, like Bird
and Plane
.
AccountableAsset
is also implemented by dissimilar, unrelated classes, like Plane
and RaceHorse
.
Horse
doesn't implement Flight.
As you can see classes (abstract or concrete) helps you build a hierarchies, letting you inhering code from the upper levels to the lower levels of the hierarchy. In theory the lower you are in the hierarchy, the more specialized your behavior is, but you don't have to worry about a lot of things that are already taken care of.
Interfaces, in the other hand, create no hierarchy, but they can help homogenize certain behaviors across hierarchies so you can abstract them from the hierarchy in certain contexts.
For example you can have a program sum the value of a group of AccountableAssets
regardless of their being RaceHorses
or Planes
.
Best Answer
An interface is like a "purely" abstract class. The class and all of its methods are abstract. An abstract class can have implemented methods but the class itself cannot be instantiated (useful for inheritance and following DRY).
For an interface, since there isn't any implementation at all they are useful for their purpose: a contract. If you implement the Interface then you must implement the methods in the interface.
So the difference is an abstract class can have implemented methods whereas a interface cannot.
The reason they are separate is so a class can implement several interfaces. Java and C# restrict a class to inherent from a single parent class. Some languages allow you to inherit from multiple classes and you could accomplish the work of an interface via a "purely" abstract class. But multiple inheritance has its problems, namely the dreaded Diamond Problem