Here the method Concrete3.pac appears to have overridden the inaccessible AbstractBase.pac. In
fact, Concrete3.pac overrides Concrete2.pac, and Concrete2.pac overrides
AbstractBase.pactherefore Concrete3.pac transitively overrides AbstractBase.pac. By
redeclaring pac as public, Concrete2 made it accessible and overridable by any subclass.[3]
[3] This illustrates why weaving in and out of a package can be confusing and should be
avoided.
18.4. Package Contents
Packages should be designed carefully so that they contain only functionally related classes and interfaces.
Classes in a package can freely access one another's non-private members. Protecting class members is
intended to prevent misuse by classes that have access to internal details of other classes. Anything not
declared private is available to all types in the package, so unrelated classes could end up working more
intimately than expected with other classes.
Packages should also provide logical groupings for programmers who are looking for useful interfaces and
classes. A package of unrelated classes makes the programmer work harder to figure out what is available.
Logical grouping of classes helps programmers reuse your code because they can more easily find what they
need. Including only related, coherent sets of types in a package also means that you can use obvious names
for types, thereby avoiding name conflicts.
Packages can be nested inside other packages. For example, java.lang is a nested package in which lang
is nested inside the larger java package. The java package contains only other packages. Nesting allows a
hierarchical naming system for related packages.
For example, to create a set of packages for adaptive systems such as neural networks and genetic algorithms,
you could create nested packages by naming the packages with dot-separated names:
package adaptive.neuralNet;
A source file with this declaration lives in the adaptive.neuralNet package, which is itself a
subpackage of the adaptive package. The adaptive package might contain classes related to general
adaptive algorithms, such as generic problem statement classes or benchmarking. Each package deeper in the
hierarchysuch as adaptive.neuralNet or adaptive.geneticwould contain classes specific to the
particular kind of adaptive algorithm.
Package nesting is an organizational tool for related packages, but it provides no special access between
packages. Class code in adaptive.genetic cannot access package-accessible identifiers of the
adaptive or adaptive.neuralNet packages. Package scope applies only to a particular package.
Nesting can group related packages and help programmers find classes in a logical hierarchy, but it confers no
other benefits.
18.5. Package Annotations
A package can have annotations applied to it. The problem is that there is no actual definition of a package to
which you can apply such annotationsunlike a class or a methodbecause a package is an organizational
structure, not a source code entity. So you annotate packages by applying the annotation to the package
statement within a source file for that package. However, only one package declaration per package can have
annotations applied to it.