classobjectoopdesign-patternsinterface

Why does class inheritance and interface implementation involve objects?


It's also important to understand the difference between class inheritance and interface inheritance (or subtyping). Class inheritance defines an object's implementation in terms of another object's implementation. In short, it's a mechanism for code and representation sharing. In contrast, interface inheritance (or subtyping) describes when an object can be used in place of another.
It's easy to confuse these two concepts, because many languages don't make the distinction explicit. In languages like C++ and Eiffel, inheritance means both interface and implementation inheritance. The standard way to inherit an interface in C++ is to inherit publicly from a class that has (pure) virtual member functions. Pure interface inheritance can be approximated in C++ by inheriting publicly from pure abstract classes. Pure implementation or class inheritance can be approximated with private inheritance. In Smalltalk, inheritance means just implementation inheritance. You can assign instances of any class to a variable as long as those instances support the operation performed on the value of the variable. ---《Design Patterns: Elements of Reusable Object-Oriented Software 1st Edition》

  1. Inheritance, isn't it simply about subclasses 'inheriting' properties and methods from the parent class. How does it become 'an object's implementation in terms of another object's implementation'? When I implement class B inheriting from class A in my code, I don't instantiate any objects at all!

  2. Isn't an interface just a special kind of abstract class? (In comparison to abstract classes, interfaces only declare methods and don't declare properties or fields.) When a concrete class implements an interface, isn't it simply a class inheriting the 'interface' and implementing the methods declared in the interface? How does this turn into 'an object can be used in place of another'? When I make class B implement interface A in my code, I don't instantiate any objects at all!


Solution

  • Terminology evolves over time; nowadays you hear "interface" and think of the interface feature of languages like Java, C#, and Go, but when Design Patterns came out in 1994, none of those languages existed yet. So when it talks about "interface inheritance", that's not what it's referring to.

    Rather, by "interface", it means the set of functionality that the class exposes to its clients. As applied to Java, that typically means its public methods — their names, signatures, and contracts — even methods that aren't specified by any "interface" in the Java sense.

    In languages like Java, all inheritance is "interface inheritance"; if class A extends class B, then it automatically implements the interface of class B. (Well, there are some borderline cases — for example, the Javadoc for java.sql.Timestamp says that although it extends java.util.Date, we should pretend that it doesn't, because it doesn't behave 100% correctly as a java.util.Date — but at least as far as the Java language itself is concerned, all inheritance is interface inheritance and some classes just have bugs. ;-)   ) But that's not true of some languages; for example, C++ lets class A inherit from class B in a "private" way, where class A has all of class B's methods but they're all private, so clients can't call them. In that kind of inheritance, the implementation is inherited, but the interface is not. This is why Design Patterns draws this distinction.