问题
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.
回答1:
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.
回答2:
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
回答3:
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.
回答4:
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.
来源:https://stackoverflow.com/questions/5770903/java-class-containing-only-private-members