How about an analogy: when I was in the Air Force, I went to pilot training and became a USAF (US Air Force) pilot. At that point I wasn't qualified to fly anything, and had to attend aircraft type training. Once I qualified, I was a pilot (Abstract class) and a C-141 pilot (concrete class). At one of my assignments, I was given an additional duty: Safety Officer. Now I was still a pilot and a C-141 pilot, but I also performed Safety Officer duties (I implemented ISafetyOfficer, so to speak). A pilot wasn't required to be a safety officer, other people could have done it as well.
All USAF pilots have to follow certain Air Force-wide regulations, and all C-141 (or F-16, or T-38) pilots 'are' USAF pilots. Anyone can be a safety officer. So, to summarize:
- Pilot: abstract class
- C-141 Pilot: concrete class
- ISafety Officer: interface
added note: this was meant to be an analogy to help explain the concept, not a coding recommendation. See the various comments below, the discussion is interesting.
Answer from Jay on Stack OverflowHow about an analogy: when I was in the Air Force, I went to pilot training and became a USAF (US Air Force) pilot. At that point I wasn't qualified to fly anything, and had to attend aircraft type training. Once I qualified, I was a pilot (Abstract class) and a C-141 pilot (concrete class). At one of my assignments, I was given an additional duty: Safety Officer. Now I was still a pilot and a C-141 pilot, but I also performed Safety Officer duties (I implemented ISafetyOfficer, so to speak). A pilot wasn't required to be a safety officer, other people could have done it as well.
All USAF pilots have to follow certain Air Force-wide regulations, and all C-141 (or F-16, or T-38) pilots 'are' USAF pilots. Anyone can be a safety officer. So, to summarize:
- Pilot: abstract class
- C-141 Pilot: concrete class
- ISafety Officer: interface
added note: this was meant to be an analogy to help explain the concept, not a coding recommendation. See the various comments below, the discussion is interesting.
While your question indicates it's for "general OO", it really seems to be focusing on .NET use of these terms.
In .NET (similar for Java):
- interfaces can have no state or implementation
- a class that implements an interface must provide an implementation of all the methods of that interface
- abstract classes may contain state (data members) and/or implementation (methods)
- abstract classes can be inherited without implementing the abstract methods (though such a derived class is abstract itself)
- interfaces may be multiple-inherited, abstract classes may not (this is probably the key concrete reason for interfaces to exist separately from abtract classes - they permit an implementation of multiple inheritance that removes many of the problems of general MI).
As general OO terms, the differences are not necessarily well-defined. For example, there are C++ programmers who may hold similar rigid definitions (interfaces are a strict subset of abstract classes that cannot contain implementation), while some may say that an abstract class with some default implementations is still an interface or that a non-abstract class can still define an interface.
Indeed, there is a C++ idiom called the Non-Virtual Interface (NVI) where the public methods are non-virtual methods that 'thunk' to private virtual methods:
- http://www.gotw.ca/publications/mill18.htm
- http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface
Abstract class vs Interface in our days
object oriented design - What are the differences between abstract classes, interfaces, and when to use them - Software Engineering Stack Exchange
Whats the difference between Interface and Abstract class? Are they not use the same way?
Abstract class vs interface - C++ Forum
Videos
I understand that the interface is used to decouple the abstraction from the implementation. As a very common example you will see with a List and an ArrayList.
List<String> interfaceList = new ArrayList<>();
You can swap out the List implementation with any other class that implements the interface.
Same thing with abstract classes. So is there a reason why you don't see this?
AbstractList<String> abstractList = new ArrayList<>();
I like to think of interfaces as contracts (this object will have property X & Y and method Z) but makes no assumptions about implementation (at least they did before Default Interface Implementations as of C# 8: https://devblogs.microsoft.com/dotnet/default-implementations-in-interfaces, although I use these sparingly if ever).
Abstract classes (and derived non-sealed classes) can be thought of as just a place to share implementation that's common between supersets of classes and their subsets. Abstract classes provide an object-oriented way of supporting the Don't Repeat Yourself (DRY) principle (https://www.c-sharpcorner.com/article/software-design-principles-dry-kiss-yagni) where the implementation you would otherwise repeat doesn't make sense outside of the context of your class hierarchy.
Interfaces & abstract classes are by no means mutually exclusive and can be used in conjunction with each other depending on the context.
abstract classes are to define a common base class for inheritance, without implementing any actual methods.
because c# does not support multiple inheritance, interfaces are the solution. a class can inherit from one base class, but it can implement many interfaces. interfaces can only be implemented. an interface can not inherit from another interface.
due to issues with inheritance chains, inheritance is often considered an anti-pattern, interface design is recommend instead. with interface design you define contacts that define properties and methods. then classes must implement. other languages use protocols/traits which are slight more feature rich than interfaces.
one past advantage with classes, was you could define default behavior, and interfaces were abstract (no implementations). But modern C# allows default implemations for interfaces.
so my recommendation is to avoid class inheritance (and never more than 1 deep, that is only inherit from base), but rather use interfaces and extension methods to extend classes.
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 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.
You could deduce the answer logically since you seem to be aware of the differences between the two.
Interfaces define a common contract. Such as an interface called IAnimal, where all animals share functions such as Eat(), Move(), Attack() etc. While all of them share the same functions, all or most of them have a different way (implementation) of achieving it.
Abstract classes define a common implementation and optionally common contracts. For example a simple Calculator could qualify as an abstract class which implements all the basic logical and bitwise operators and then gets extended by ScientificCalculator, GraphicalCalculator and so on.
If you have common implementation then by all means, encapsulate the functionality in an abstract class to extend from. I have near 0 PHP experience, but i don't think you can create interfaces with non constant fields. If the fields are common between your instance classes then you are forced to use an Abstract class, unless you define access to them via getters and setters.
Also, there seems to be no shortage of results in Google.