Imagine you want to represent a variety of devices, and comes up with
the following UML diagram:
Note that it is possible to gather that e.g., the Instructions()
method in the Abacus class is overriding the Instructions() method
in the ComputingDevice class because it has the same signature: this
can be the case only because it is overriding the inherited abstract
method.
Your abstract classes are “completely abstract”, in the sense that all
of their properties and methods are abstract, but it serves your purpose
just well:
you do not want “ComputingDevices” to exist in isolation, but you want
any class representing a computing device such as the
Abacus, the
Pascaline or
the Turing Tumble to
have an Instruction per seconds property, and a method to display
instructions.
similarly, you want any “ElectronicalDevice” to have properties
pertaining to their voltage and frequency, as well as a method to
display a safety notice.
A class that is “completely abstract” actually forces you to enforce a
series of constraints and is a good way of making sure that you are
consistent e.g., with the naming of your methods, the accessibility of
your properties, or the return type of your methods.
Then, you would like to add a “Computer” class, but face an issue:
classes can inherit only from one class directly, but of course a
computer is both an electrical device and a computing device. A
solution is to switch to interfaces.
Explanations
Interfaces are completely abstract classes: they do not implement
anything, they simply force classes inheriting from them (we actually
say that realizes them) to implement certain features.
In Diagram
Interfaces are prefixed by the «Interface» mention, and have all their
properties and methods marked as abstract (so, in italics). A class
can “inherits” from multiple interface (we say that it realizes
multiple interfaces), and this is marked with an arrow with an open
triangle end and a dashed line1.
An Implementation
Implementing such interfaces and their realization could be done as
follows: