Conspicuously missing access specifier
I am wondering why there is an access level that allows access to anything in the same package but not one that allows access only to subclasses. Doesn't this seem like a really obvious type to have?
Without it, encapsulation and extensibility seem to be mutually exclusive aims. If you make things private, your subclasses cannot access them. If you make them protected, they are open to anything in the package.
Is there a good reason they chose to do things this way?
Drake
[502 byte] By [
Drake_Duna] at [2007-10-2 15:44:43]

don't have other things in the package :)
> don't have other things in the package :)
Well yeah... I guess a given package is usually within one person or team's control. But then why isn't the standard practice to mark most things with "protected" and some things with "private", rather than the reverse?
I am starting to think maybe I should be marking stuff "protected" instead of "private".
Drake
Maybe a package is considered to consist of stuff related each to the other so closely that they preserve mutual access besides private things. Cf. the possibility to close (seal?) a package.
> I am wondering why there is an access level that
> allows access to anything in the same package but not
> one that allows access only to subclasses. Doesn't
> this seem like a really obvious type to have?
>
> Without it, encapsulation and extensibility seem to
> be mutually exclusive aims. If you make things
> private, your subclasses cannot access them. If you
> make them protected, they are open to anything in the
> package.
>
> Is there a good reason they chose to do things this
> way?
>
> Drake
the sub class supposedly has an is a relationship with its super class; from this pespective, it should have access to all things in the super class. as a result, the burden is upon the designer of the a class to make sure it will be safe when the class is subclassed. if you dont have time to do this, then use private and let the subclass do the extra work. otherwise use protected. use private ususally is safer.
other classes in the same package do not have this is a relationship. hope you see the difference.
> But then why
> isn't the standard practice to mark most things with
> "protected" and some things with "private", rather
> than the reverse?
I think most notably because of the design burden associated with protected members. You expose them as part of the visible API, with all associated maintenance burdens. You'll also want to make sure subclass implementations won't be able to violate any contracts you've established.
I've seen far too many cases of members that seem to be protected because "some subclasses may find it neat", or similar reasoning. I.e., cases where extensibility is provided as a feature rather than a design decision.
DaanSa at 2007-7-13 15:37:32 >

> Is there a good reason they chose to do things this
> way?
There's a rule that you cannot reduce accessibility of a method when you override it (e.g. you can't override a public method by a private method). That rule therefore requires that the access specifiers are well-ordered, all comparable to each other, form a hierarchy, however you want to say that.
If the default specifier only allowed access to everything in the package then it would be incommensurable with the protected specifier. It wouldn't be higher and it wouldn't be lower. This can't be allowed as per the previous paragraph. Therefore the protected specifier was made to allow access to everything in the package as well, so that it could be compared to the default specifier.
>
> Without it, encapsulation and extensibility seem to
> be mutually exclusive aims. If you make things
> private, your subclasses cannot access them. If you
> make them protected, they are open to anything in the
> package.
>
That doesn't bother me. I use protected solely for access via subclasses. I never use it for access from within the package. It doesn't bother me that it could be used that way.
> If you make things
> private, your subclasses cannot access them. If you
> make them protected, they are open to anything in the
> package.
I can't off hand think of a circumstance under which you would be unable to break an implementation by non-derived access of a protected method, but in which derived access of the same method would be safe.
Can you suggest one?
Ignore me. I just thought of lots. It must be time for a coffee.
I guess you could think of two possibilities for making 'protected' more restrictive:
> package-private (exists). Subclasses cannot use the functionality but classes within the package can. Why use this? Here are two examples: a DAO in the same package as the model class it persists (make the DAO's methods package-private and thus tie the DAO explicitly to its model object with access modifiers). Another would be in Swing, have a GUI helper class have all package-private methods (same thinking, this would tie the helper to the GUI class's package and prevent others from using it).
> friend (does not exist). Subclasses can use the functionality of the super-class but other package members cannot. I guess this is what you are referring to. I have wanted 'friend' as an access modifier in the language for a long time. It's not a true 'friend' modifier, as you *must* subclass to take advantage of the modifier, unlike in C++.
- Saish
Saisha at 2007-7-13 15:37:32 >

> friend (does not exist). Subclasses can use the
> functionality of the super-class but other package
> members cannot. I guess this is what you are
> referring to. I have wanted 'friend' as an access
> modifier in the language for a long time. It's not a
> true 'friend' modifier, as you *must* subclass to
> take advantage of the modifier, unlike in C++.
Yes, that is exactly what I would like to see. And it seems like a really obvious feature to have to me.
How does friend work in C++? Does it let you designate objects for whom you wish to allow access? That is another one that I have occasionally thought would be nice.
Drake
> > friend (does not exist). Subclasses can use the
> > functionality of the super-class but other package
> > members cannot. I guess this is what you are
> > referring to. I have wanted 'friend' as an access
> > modifier in the language for a long time. It's not
> a
> > true 'friend' modifier, as you *must* subclass to
> > take advantage of the modifier, unlike in C++.
>
> Yes, that is exactly what I would like to see. And
> it seems like a really obvious feature to have to
> me.
I'm not sure why you'd want that. I belive a part of a package's purpose is to provide a way for classes that work together to perform a given family of functions to share some things without it being available outside that package.
It's like taking what a class does, and giving it a little broader coverage. Without package-private, you'd have to either expose a bunch of stuff you don't want to expose, or cram a lot more into a single class than what belongs there.
Now, if you accept that, then by analogy, allowing access to subclasses but not within the package would be somewhat like allowing access in subclasses, but not to other parts of the parent class.
Basically you've got a widening circle of association. Stuff in the same class is the most closely associated, then stuff in the same package, then stuff in subclasses, then the rest of the world. There's no reason to deny access to a more closely associated class that's available to a "more distant" one.
jverda at 2007-7-13 15:37:32 >

> I'm not sure why you'd want that. I belive a part of
> a package's purpose is to provide a way for classes
> that work together to perform a given family of
> functions to share some things without it being
> available outside that package.
Well, in theory that could be the case, but in reality packages aren't usually used that tightly, are they? What does an ArrayList have to do with a Date?
Association by package can be very close or very loose depending on how people program... but it seems like inheritence is a very close relationship by necessity. I am having a hard time convincing myself that the presence of two classes in the same package implies a deeper relationship than one subclassing the other!
Drake
> > I'm not sure why you'd want that. I belive a part
> of
> > a package's purpose is to provide a way for
> classes
> > that work together to perform a given family of
> > functions to share some things without it being
> > available outside that package.
>
> Well, in theory that could be the case, but in
> reality packages aren't usually used that tightly,
> are they? What does an ArrayList have to do with a
> Date?
>
Simple! They are both util. (Okay, doesn't satisfy me either). It's ironic you picked Date. One of the most deprecated classes in the API. Date (and Calendar) are both somewhat broken. However, JVerd is right. Just because Sun did not get it right does not mean that packages themselves do not connote an additional type of source organization.
> Association by package can be very close or very
> loose depending on how people program... but it seems
> like inheritence is a very close relationship by
> necessity. I am having a hard time convincing myself
> that the presence of two classes in the same package
> implies a deeper relationship than one subclassing
> the other!
Don't fret. You do not have to convince yourself. The language already makes the distinction for you. :^)
JVerd is correct. But he refers to art whereas you invoke science. Technically (and I guess linguistically) there is nothing stopping you from developing your own packages that subvert existing access modifers. (Really, the term 'subvert' is relative, as I hope the above indicates). From a literal perspective, Drake, you are correct. However, JVerd is equally correct.
Packages exist to organize your source. One of two possible modifiers exist in the language to restrict other class use of your methods via packages. Rather than worrying about how a malicious developer could add a Java source file to your package and invoke functionality you do not want, why not instead invest said mental energy in making your packages contain like classes needing like functionality?
There are lot's of other aspects of the language that could be improved. But, aside from introducing Friend functions ala C++, these are the only tools available to you (and everyone else). :^)
- Saish
>
> Drake
Saisha at 2007-7-13 15:37:32 >

> > I'm not sure why you'd want that. I belive a part
> of
> > a package's purpose is to provide a way for
> classes
> > that work together to perform a given family of
> > functions to share some things without it being
> > available outside that package.
>
> Well, in theory that could be the case, but in
> reality packages aren't usually used that tightly,
> are they?
Mine generally are.
> Association by package can be very close or very
> loose depending on how people program.
I know. I was speaking to what I think the intent--or one of the main intents--of packages is.
> .. but it seems
> like inheritence is a very close relationship by
> necessity. I am having a hard time convincing myself
> that the presence of two classes in the same package
> implies a deeper relationship than one subclassing
> the other!
Perhaps you don't think of a package the way the language designers did? ;-)
jverda at 2007-7-20 22:42:58 >

> Is there a good reason they chose to do things this
> way?
>
> Drake
not much, mostly a java personal prefrence.
in c++ protected things are accessible only in sub classes, but protected is a measured accessibility. maybe java feels safe to make it accessible by other classes within the package.
however, up till jdk 1.01, you could actually use private and protected together to make it accessible only to sub classes. this type of protection was removed since jdk 1.02. i personally think java shouls put it back, if not too much trouble.
jverda at 2007-7-20 22:42:58 >

another thing i could think of why c++ makes it accessible only via sun classes was because the 'package' concept in c++ was rather weak initilally, namesapces are something close to java packages, but it was only in the later years of c++, it became more obvious.
jverda at 2007-7-20 22:42:58 >

What package would I find the Null object in daffy?
jverda at 2007-7-20 22:42:58 >

> What package would I find the Null object in daffy?try the default, in the runtime machine.
jverda at 2007-7-20 22:42:58 >

> > What package would I find the Null object in
> daffy?
>
> try the default, in the runtime machine.
Oh-ho. I am surprised you answered. What do you mean the default? The default package?
Please point me to the package that contains the null object daffy. Please educate me.
jverda at 2007-7-20 22:42:58 >

> > What package would I find the Null object in
> daffy?
>
> try the default, in the runtime machine.
Wrong.
First their is no package "in the runtime machine." That's just meaningless.
Second, there is no null object, which you'd know if you had read and understood the JLS.
jverda at 2007-7-20 22:42:58 >

And I know you will assert "Gosling is wrong", but here is the FIRST EDITION of the JLS and what it has to say about access modifiers:
6.6.1 Determining Accessibility
* Whether a package is accessible is determined by the host system (7.2).
* If a class or interface type is declared public, then it may be accessed by any Java code that can access the package in which it is declared. If a class or interface type is not declared public, then it may be accessed only from within the package in which it is declared.
* A member (field or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access:
o If the member or constructor is declared public, then access is permitted. All members of interfaces are implicitly public.
o Otherwise, if the member or constructor is declared protected, then access is permitted only when one of the following is true:
# Access to the member or constructor occurs from within the package containing the class in which the protected member is declared.
# Access occurs within a subclass of the class in which the protected member is declared, and the access is correct as described in 6.6.2.
o Otherwise, if the member or constructor is declared private, then access is permitted only when it occurs from within the class in which it is declared.
o Otherwise, we say there is default access, which is permitted only when the access occurs from within the package in which the type is declared.
6.6.2 Details on protected Access
A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object. Let C be the class in which a protected member or constructor is declared and let S be the subclass of C in whose declaration the use of the protected member or constructor occurs. Then:
* If an access is of a protected member (field or method), let Id be its name. Consider then the means of qualified access:
o If the access is by a field access expression of the form super.Id, then the access is permitted.
o If the access is by a qualified name Q.Id, where Q is a TypeName, then the access is permitted if and only if Q is S or a subclass of S.
o If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
o If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
* Otherwise, if an access is of a protected constructor:
o If the access is by a superclass constructor invocation super(. . .), then the access is permitted.
o If the access is by a class instance creation expression new T(. . .), then the access is not permitted. (A protected constructor can be accessed by a class instance creation expression only from within the package in which it is defined.)
o If the access is by an invocation of the method newInstance of class Class (20.3.6), then the access is not permitted.
I further went and checked the 'addenda' between First and Second editions in the JLS. There is absolutely no mention whatsoever of what you are trying to assert.
To all who are unaware: do not listen to Daffy, you will be dumber for having done so. @Daffy: Please stop trying to confuse others. We already know you are confused.
- Saish
Saisha at 2007-7-20 22:42:58 >

