Why are many Android API classes non-final, even though they are not explicitly documented for inheritance?

StackOverflow https://stackoverflow.com/questions/8091624

  •  26-02-2021
  •  | 
  •  

Question

Effective Java (Joshua Bloch) Item 17 says :

"Design and Document or inheritance or else prohibit it"

However, just a cursory glance through the Android APIs reveals that most of the API classes are non-final; which is OK if they are also documented for inheritance (View of Activity, for example). But there are also several non-final classes, but the documentation makes no mention about the inheritability of these classes. Just some arbitrary examples to illustrate my point:

  • The classes representing the System Services (WifiManager, NotificationManager ...)
  • Utility classes like UriMatcher.
  • Some hardware-specific classes like Camera.

Openness and extensibility being the philosophy of Android, is the convention reversed here? Meaning, could one assume that all of the Android API classes are designed to be inherited (whether explicitly documented or otherwise); unless declared final?

Was it helpful?

Solution

Just my €0,02: Clean OO design by the book is one thing, making things work for all possible use cases in practice is another. The principles of clean OO design sometimes are somewhat of academic nature. - And maybe a little bit of black and white.

Think for instance about who uses the Android API provided by google: It's not only app developers but also device manufacturers who need to specialize general APIs for their devices.

So, for me, SW design is neither black nor white in most cases; the shades of grey are important.

And finally: In practice I have seldom (read: never) seen problems caused by "carelessly" omitted final keywords (on classes), while unreflected overuse of final (often caused by thoughts like "my code is sooo [great | ugly], no one will actually ever want to modify it through inheritance") can be quite a pain.

"I know that I know nothing" seems to fit here: It is presumptuous to claim that one knows all the crazy, ingenious, creative, smart,... ideas of others for how one's code may be used in the future beforehand.

OTHER TIPS

The Android developers went to great lengths to ensure that extensibility, while not recommended in many cases, is possible. The motivation behind this appears to be related to testing environments.

For instance, it would be much more difficult to create a faux WifiManager for the purposes of creating unit tests if it were finalized. Without the finalization, it is trivial to subclass the WifiManager (e.g. to mimic "unexpected" wifi disconnection during operation) and return an instance of this subclass from a customized testing Context.

So while you will probably never find a reason to implement a subclass of the these classes in an application that you ship to the end users, the flexibility is there to allow you to extend them if it is necessary for one reason or another.

In the case of utility classes, the answer is simply that the utility of the class is not diminished by allowing the developer to subclass; in many cases, a developer can achieve more understandable code reuse by inheritance than by aggregation and delegation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top