I am reading the first chapter of the Gof book. Section 1.6 discusses about class vs interface inheritance:
Class versus Interface Inheritance
It’s important to understand the difference between an object’s class
and its type. An object’s class defines how the object is
implemented.The class defines the object’s internal state and the
implementation of its operations.In contrast,an object’s type only
refers to its interface–the set of requests on which it can respond. An
object can have many types, and objects of different classes can have
the same type.Of course, there’s a close relationship between class and type. Because
a class defines the operations an object can perform, it also defines
the object’s type . When we say that an object is an instance of a
class, we imply that the object supports the interface defined by the
class.Languages like c++ and Eiffel use classes to specify both an object’s
type and its implementation. Smalltalk programs do not declare the
types of variables; consequently,the compiler does not check that the
types of objects assigned to a variable are subtypes of the variable’s
type. Sending a message requires checking that the class of the
receiver implements the message, but it doesn’t require checking that
the receiver is an instance of a particular class.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.
I am familiar with the Java and JavaScript programming language and not really familiar with either C++ or Smalltalk or Eiffel as mentioned here. So I am trying to map the concepts discussed here to Java’s way of doing classes, inheritance and interfaces.
This is how I think of of these concepts in Java:
In Java a class is always a blueprint for the objects it produces and what interface(as in “set of all possible requests that the object can respond to”) an object of that class possess is defined during compilation stage only because the class of the object would have implemented those interfaces. The requests that an object of that class can respond to is the set of all the methods that are in the class(including those implemented for the interfaces that this class implements).
My specific questions are:
- Am I right in saying that Java’s way is more similar to C++ as described in the third paragraph.
- I do not understand what is meant by interface inheritance in the last paragraph. In Java interface inheritance is one interface extending from another interface. But I think the word interface has some other overloaded meaning here. Can some one provide an example in Java of what is meant by interface inheritance here so that I understand it better?
- Java classes are similar to C++ as described in the third paragraph. Java interfaces are a different concept.
- In Java, a class implicitly specifies both an interface in the GoF sense and the implementation. By contrast a Java interface explicitly specifies an interface in the GoF sense and doesn’t specify an implementation. In both cases inheritance implies interface inheritance. Only in the case of class inheritance does it imply implementation inheritance.
For a better example of the distinction, I highly recommend learning just enough Ruby to understand how a class can use method_missing
to proxy off of an unrelated object. This provides a very explicit example of interface inheritance without implementation inheritance. (Bonus, Ruby’s OO model is the same as Smalltalk’s while having a more familiar syntax, which gives you a leg up on the rest of the book.)
I found this comment very interesting and I believe it could contribute positively with the question:
I once attended a Java user group meeting where James Gosling (Java’s inventor) was the featured speaker. During the memorable Q&A session, someone asked him: “If you could do Java over again, what would you change?” “I’d leave out classes,” he replied. After the laughter died down, he explained that the real problem wasn’t classes per se, but rather implementation inheritance (the extends relationship). Interface inheritance (the implements relationship) is preferable. You should avoid implementation inheritance whenever possible.
https://www.javaworld.com/article/2073649/core-java/why-extends-is-evil.html
- Yes, Java classes are similar to C++ classes in this regard.
- Yes, in this case, interface doesn’t really mean
interface
language construct present in Java and C#. In this case it has more abstract meaning. I think you can equate it to public methods and fields, that can be called on the object.
Class inheritance here means standard subtyping, where child class inherits behavior of it’s parent. Interface inheritance is much more related to polymorphism and virtual method calls. It means child class can “accept and respond to messages” that parent can accept and respond to. The whole “describes when an object can be used in place of another” is basically definition of subtype polymorphism.
2
@Euphoric has already answered both of your questions. I just wanted to extend his explanation with some further clarification.
It is possible to perform “Class inheritance” without interface being inherited completely. It has been more than 5 years that I have touched Java, but, if I remember correctly, “protected” methods becomes “private” for a class when inherited outside the package. Now, in Java “protected” member will be part of interface of an object but “private” member isn’t (anything which you can access using an instance of class is part of it’s interface, which in the case of Java is “public” and “protected”, I believe). In this scenario the method is inherited (that is — can be used within subclass as it’s own) but you cannot call the method on instance of a subclass. Thus, you get class inheritance without interface being inherited.
For your 2nd question about interface inheritance:
Interface inheritance is logically similar to class inheritance, but the real reason it is provided is for providing flexibility. For example, consider interfaces of concurrent utility package in java. At top level we have executor interface which has method execute exposed and another interface named executorService extends executor interface. Now if you are not interested in features provided by executorService then you can go for implementing executor Interface, otherwise you just need to implement executorService interface and you will have all features of parent interface. This design can be observed in most of the java packages, be it Collection framework or Concurrent utilities.
1