I agree with Daniel that for methods, visibility only makes sense for the method declarations and should affect (only) the places you can call the method. But, I agree with Arjan that there should be a way to prevent specializations of a method from outside the package it is defined in.
It makes sense that a class's visibility would affect the ability to implement a method for that class. For example, if a class
C is private to a package
a.b.c, it should not be possible to define a multimethod that has an
a.b.c.C argument or return type outside of package
a.b.c. Similarly, it should not be possible to define a public method
M in package
a.b.c that is declared to accept parameters of type
a.b.c.X or returns type
a.b.c.X.
The visibility of a class's constructor should be at least as restrictive as the class's visibility. For example, it doesn't make sense to have a public constructor for a package-private class. However, it does make sense to have a package-private constructor for a public class. It might be useful to have
protected for constructors--A
protected constructor of class
X can only be used by a constructor for a subclass of
X. Then you could also have
package protected which would allow use of the constructor by a subclass of
X as well as by any code defined in the same package as
X.
Beyond constructors, I don't think any modifier giving subclasses special privileges is very useful. Presumably, it would only apply to the classes' initializer and the default value expression for its fields.
I agree with Vulcannis when he says that it is "unsettling that units of storage, the source file, are being given semantic meaning in the language." But at the same time it does seem useful to have source-file level visibility as long as a single package can be spread across multiple source files. Perhaps a good way of handling this would be to have a
package visibility modifier instead of
private. A symbol (class, method, field, value) without a visibility modifier would be visibile only within the source file it is declared in. To grant access to other source files in the package, it must be marked with a
package modifier. To grant access to other packages, it must be marked with a
public modifier. Then you don't need a
private to mean "this source file only" at all.
It seems like selective export like in Eiffel seems like it can only apply at the package level since methods are seperate from classes. E.g. package
A could export symbols
f,
A,
B.c to packages
B and
C. I am not sure how useful it is.
One important aspect is what the
default visibilities should be. My preference is to make everything source-file-private by default. My second preference is to require a visibility modifier for every package-level construct.
--
BrianSmith - 04 Feb 2004