Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 631
curioustechizen Avatar asked Nov 11 '11 08:11

curioustechizen


People also ask

How do you inherit final class in Kotlin?

In Kotlin, unlike Java, all the classes are implicitly marked final by default. If you want to inherit from a class, you have to explicitly add open keyword before the class declaration.

Why multiple inheritance is not supported in Java?

Java doesn't support multiple inheritances in classes because it can lead to diamond problem and rather than providing some complex way to solve it, there are better ways through which we can achieve the same result as multiple inheritances.

Which class Cannot be inherited in Java?

What cannot be inherited ? Constructors. Although, the subclass constructor has to call the superclass constructor if its defined (More on that later!) Multiple classes.

Do subclasses inherit constructors?

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.


2 Answers

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.

like image 162
JimmyB Avatar answered Oct 11 '22 20:10

JimmyB


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.

like image 37
Greyson Avatar answered Oct 11 '22 19:10

Greyson