On 2008-02-17 16:41 +0100, Lew allegedly wrote:
**** DIScLAIMER *****
Only in the present disclaimer does "you" in this post refer directly
to you, Lew.
*********************
Protected access supports encapsulation less than private. The
problem with protected access is that anyone can create a subclass
and futz with the protected thing.
And this is precisely where I veer off. As far as I see the above is the
only substantial, general argument that can be made in favour of private
versus protected. I find that argument unacceptable and its implications
matter for concern.
I do not advocate making everything protected. I would generally
recommend making all variables private. Some types of fields suffer
protected access rather well: JComponent's EventListenerList comes to
mind. What I'm about is the rule of thumb. IMO the rule of thumb should
be: private for fields, protected for methods. That doesn't mean the end
result will have to look like that; it's a rule of thumb, it means that
every time you deviate from it, you should do so with a reason, good one
or bad one.
What pisses me off with the argument given above is this "ah! if I leave
that open they'll futz with my protected thing" attitude (any Freudians
here?). So fucking what? Look lad: I'm extending your classes, and I
KNOW WHAT I'M DOING. And even if I don't? I've extended classes to do
some funny things their original author surely wouldn't have approved
of. I've seen some parts of my libraries extended, or should I say
distorted, such that a reasonably well-conceived structure was
shattered. So what? How are they supposed to learn otherwise? Sure, once
I wasn't there anymore, it may have in some cases led to the
less-than-agreeable outcome of a library becoming messed up. So what? I
do not live off other people's work so this is quite literally not my
own business.
Am I really the only one who's had to wade through the innards of a
public API (I have Swing in mind), battling to twinkle a slight detail,
inaccessible through public means, of its behaviour by extending classes
and cursing its authors because his attempts were crushed by a single,
private variable which he would have needed to access and which he
/knew/ he could access securely or at least was ready to face whatever
bad consequences may have arisen?
Neither do I think classes should be made final. There is one single
case where final classes and heavy-hiding are not only acceptable but
virtually mandatory, and that's where security issues are at stake. But
in all other cases, at least all that come to my mind, all this locking
up tight is but another recurrence of the hysterical attitude inferred
above.
The usual argument I hear goes approximately like this: "don't make a
class or parts of a class extendible unless they're specifically
tailored to be so".
No. Three times no. (no.)
For classes which are made to be extended, especially abstract classes,
the matter is clear. For classes which are destined _not_ to be
extended, also. Which leaves us with a great majority of classes of
which can't be told that extending them would necessarily be a bad
thing. Note: not "*could*" be a bad thing, "*necessarily would*" be a
bad thing. Why should these be locked up? What's so damn wrong about
letting people decide for themselves, taking responsibility for
themselves? What's so damn wrong with assuming there could be other
people beside oneself who know what they're doing? Do you have such a
poor opinion of your code that you can only assume it'll break if
somebody else touches it?
Furthermore, a solid design for a class already carries with it such
techniques as would be necessary to tailor the class for extension use.
IOW, if you have to make a class specifically to be extendible, then
give it a solid design and you've already dealt with half of the job.
There should not be two spheres of design: one design for the class
hierarchy and one for the classes' internals. There should be but one
sphere with different layers: "macroscopic" layers of lower-level,
higher-level and so forth classes, "microscopic" layers inside the
class, with lower-order and higher-order methods et caetera. The whole
design ought to flow naturally from the highest to the lowest layers --
there shouldn't be any no-trespassing zone in between.
Within a class, you would have a gradient of layers from public use (the
"interface"), via general implementation use, to highly specific
implementation use. A smaller or larger, central part of this gradient
qualifies for protected access -- generally speaking. protected access
does not /break/ encapsulation, it is an /essential part/ of proper,
multi-layered encapsulating design.
Consequently, I do advocate against the idea of locking one's own code
up by default. I have yet to be confronted with an argument which would
call for a reversal of the rule of thumb described earlier, and which
would withstand the test of reason.
DF.