Effective Java Item 17: Design and document for inheritance or else prohibit it

In item 16, we discussed the fact that:

inheritance violates encapsulation

The sub class may break when overriding a method without knowing the implementation detail of a super class. Click here for a concrete example.

When you are implementing a class that is designed for inheritance, it is important to document the implementation detail of every overridable method. This may violate the principle that “we should always document what a method does, instead of how the method does it”. However, this is an unfortunate fact caused by “inheritance violates encapsulation”.

There are a few more rules that a class needs to obey in order to allow inheritance. Constructor must not invoke overridable methods. This is because the overrided method in the constructor of super class will always be invoked before the constructor of the sub class. This may cause invocation of an object before that object has been initialised properly.

Because clone and readObject behave a lot like a constructor, so for the same reason, neither clone nor readObject may invoke an overridable method.

When a class is not designed for inheritance, programmers should disallow subclassing for that class. This can be done by mark that class as final, or make the constructor private and provide a public static InstanceOf method.