Interfaces are the basis of proper composition and shine in relationship with many design patterns (e.g. the Command pattern). As such, they are fundamental to sound OO design. Teach interfaces as the rule and class inheritance as the exception. Class inheritance (extends) is mostly unnecessary and widely misunderstood and leads to rigidity while promising flexibility. Interface implementation, on the other hand, leads to a more functional design and stimulates creativity.
A proper way to teach interfaces is to create a bit of undo functionality, with an interface 'Command', having two methods 'do' and 'undo' and a command stack.
Interfaces should be:
- Coherent (the methods should have an obvious relationship, such as do() and undo(), fork() and join()),
- Obvious to implement (the pre- and post-conditions of each method should be easy to understand, even though the implementation of the interface might be complex). This guarantees encapsulation and reuse,
- Well named (generally the name should be an adjective, although exceptions can be made, such as the Command above).
Finally, interfaces generally define the façade of a more complex system, in order to insulate implementation changes in a future release from the users of this system.