2

Lately I met a situation where I needed to create a custom VideoView to my android application. I needed an access to the MediaPlayer object and to add some listeners.

Unfortunately (for me), all members of the VideoView class are private, so even extending the class wouldn't help me to gain access to its MediaPlayer object (or anything else), I had to make a complete duplicate of the class with my modifications.

Well, although it is sound like I'm complaining for the "hard work", it is easier than extending the class in this case (since all the source is available...), but it made me really doubt this method of information hiding. Is this a better practice than leaving main components available to modification / access (protected, not public)? I mean, I understand that if I extend the VideoView class, someday maybe they'll change something in the VideoView class and I might have troubles, but if they'll change the class, my own (duplicate) version will have a bigger difference from the VideoView class, and my goal is not to create my own video view, but to extend the available VideoView.

MByD
  • 129,681
  • 25
  • 254
  • 263

4 Answers4

4

I usually prefer composition rather than inheritance in such situations.

EDIT:
It's safe to use inheritance when both subclass and super class are in the control of the same programmer but implementation inheritance can lead to a fragile API. As you mentioned if superclass implementation changes then subclass can break or more worst - will do unintended things silently.

The other approach would be to have private field that references an instance of the existing class (VideoView) known as composition and each instance method in the new class invokes the corresponding method on the contained instance of the existing class and returns the results. This wrapper approach can be referred as 'Decorator' pattern as well

Premraj
  • 7,462
  • 8
  • 43
  • 65
  • See also [A Conversation with Erich Gamma, Part III](http://www.artima.com/lejava/articles/designprinciples4.html) – trashgod Apr 24 '11 at 14:39
  • @Falcon-this is what I thought you meant. In this case this pattern is irrelevant for me. – MByD Apr 24 '11 at 20:38
  • @trashgod - I really enjoyed the link you posted – MByD Apr 24 '11 at 20:45
  • @MByD - I feel this or some variant of this you should look for.. and about VideoView - I feel they have did the right thing :) – Premraj Apr 25 '11 at 06:56
4

When a programmer makes something private, they're making a bet that nobody else will ever need to use or override it, and so there will be a payoff from the information hiding. Sometimes that bet doesn't come off. Them's the breaks.

Tom Anderson
  • 42,965
  • 15
  • 81
  • 123
  • 1
    +1 See also [Bloch](http://java.sun.com/docs/books/effective/). Item 16: "Favor composition over inheritance" and Item 17: "Design and document for inheritance or else prohibit it" elaborate on this difficult trade off. – trashgod Apr 24 '11 at 21:16
1

I can't speak for the reasoning of the particular VideoView developers, but if you're developing an API, and determine that the state represented by certain data needs to always follow certain rules in order to maintain the integrity and intended purpose of the object, then it makes sense to make the member vars private so you can control their modification.

It does limit what other devs can do, but I assume that's the point. There's some things that, if they were to be changed, you would want it to go through discussion and verification amongst the group that has governance over the API. In that case it makes sense to privatize so that modifications to it can't get out of hand outside of the group's oversight.

I don't know that there's a static rule of thumb that determines when something needs to fall into this category, but I can definitely see the use in certain cases.

roberttdev
  • 32,556
  • 2
  • 18
  • 23
  • as I agree with what you say, I think that by designing such a class you completely lose the possibility to inherit from it, which is one of the main concepts of OOP, and for a reason. If I make changes in a subclass that violate the integrity of the class, it is my responsibility, and affect only me / my costumers. – MByD Apr 24 '11 at 14:11
  • @MByD - If you're writing an API then you can design the class for inheritance like - SurfaceView , which can be extended but VideovView is a widget implementation so it's good to protect variables to keep the behavior intact.. for the end users like us may it is expected to create the implementation of SurfaceView. – Premraj Apr 24 '11 at 14:21
  • You definitely do (although you can mitigate it somewhat by providing thorough accessor methods). But it's really up to the people whose job it is to govern the code. They get to make the decision there is something they don't want the other devs under them (or using their API) to mess with without it being OK'ed by them. – roberttdev Apr 24 '11 at 14:25
  • Another thing to point out is.. in such open source projects, they are likely looking to keep the average person checking in API updates from messing with this. If it's privately set up like this only the architects with top access can make the decision to change it. That way checkins can't screw it up for everyone using the API. – roberttdev Apr 24 '11 at 14:27
1

When I read all the enlightening answers (and comments) and commenting to those I realized that I expected something which is irrelevant from some classes. In the case of VideoView fr example, this class is already the last in the inheritance chain. It should not be extended, as it is one logical unit, very specific and very tight, for a very specific purpose. My needs, to get special states from the view and the MediaPlayer, were needs for QC purposes, and such needs really shouldn't be considered when providing a product which is a closed unit (although the source is open). This is a reasonable argument and I find it satisfing. Sometimes not every concept of OOP should be implemented. Thank you all for the responses.

MByD
  • 129,681
  • 25
  • 254
  • 263