Java Scope - Island of Sanity

Island of Sanity



Computers

Java Scope


A point in the design of Java puzzles me. I think this is a design flaw, but maybe there's a good reason for it that I just don't see.

Java provides four levels of scope for functions and variables:

Scope Accessible by
Private Only by the class in which it's defined
Default (package) By the class in which it's defined and any other class in the same package
Protected By the class in which it's defined, any other class in the same package, and any sub-classes of the class in which it's defined
Public By any module

If you're a Java programmer you probably know this. If you're familiar with some other object-oriented language it shouldn't be incomprehensible. (The idea of a package may be unfamiliar. A package is just a grouping of related classes.)

I find this a very odd set of scopes.

Public and private are obvious enough, a minimum and maximum. Any set of scopes would likely include these.

But it seems to me that the most common, obvious scope that I would want would be: Accessible to the defining class and all its subclasses (like C++'s idea of "protected"). I think this should be the default.

When I create a new class, I don't normally know all the subclasses it will have. Often I have no intention of creating a subclass, but then later, on another project, I find occassion to re-use this class and at that time create a subclass. Very frequently I find it desirable to create a subclass to a class created by someone else. When I extend a class written for another project or written by someone else, my child class is often in a different package from the parent class. When I extend a class, I often find it necessary to access functions or data in the parent class.

This is where Java's scopes are awkward. There is no scope that allows access by the defining class and its subclasses and nothing else. The closest is "protected", but that also gives access to every other class in the package. This is far too broad. I am hard pressed to think of a time when I was working on a project where it made sense to share data among all the classes in a package. I rarely have any more cause for a class to share data with another class in the same package than for it to share data with a class in a different package.

But it makes perfect sense for a child class to want to access data from its parent that is inaccessible to the "general public". A child often overrides one or more functions from the parent -- that's the whole point of inheritance, right?, take some and override others. It is likely that this means it will have to use at least some of the same data. But the default behavior is that data is not available to a child class. (Unless it's in the same package, which may not always be logical -- or even possible, if the package is from an outside source.) Of course there might be reasons why a programmer would not want an overriding function in a child class to have access to the same data used by the overridden function. But this sounds more like the exception than the rule. Why is it the default? Especially when the default gives access to every other class in the package.

I notice that Java's scopes form a strict hierarchy. Private is the most restrictive, package opens it up some, protected opens it more, and public opens it the most. Any class that can access a package member can also access a protected or public member, and any class that can access a protected member can also access a public member. Each is a superset of the more restrictive. Adding a scope that allows children to access data but not other package members would break this hierarchy. Perhaps there is some reason why this would be difficult to implement or would cause some other problem.

Still, why not make the scopes:

Scope Accessible by
Private Only by the class in which it's defined
Family By the class in which it's defined and all its children
Neighborhood By the class in which it's defined, its children, and any other class in the same package
Public By any module

Make the default be Family. Then the normal case would work without any extra effort.

© 2007 by Jay Johansen


Comments

No comments yet.

Add Comment

Name
E-mail
Comment