Package- a collection of classes and interfaces grouped
together as a logical unit.
Packages have an API (Application Programmers Interface) which
contains the public classes and interfaces and their public
members. Think of Packages as another level in Layers of Java
Components. (See Fig.1)
examples:
java.awt-Java's Graphics package for building user
interfaces
java.io-Java's package for interacting
with the file system
Abstraction-as software packages grow larger, the
sheer number of different classes can be overwhelming,
so we try to organize them in some logical way.
Class hierarchies do that to some extent,
but often several hierarchies are related so the class
hierarchy doesn't capture their relationships. So, packages
provide an abstraction for logically related classes, and a
way to think about building systems in layers. In
Figure 1, we can think of the application as being built on
top of java.lang, java.awt, and cs101.canvas. In reality,
there is further layering, since java.awt builds on java.lang
and cs101.canvas builds on both java.lang and java.awt.
However, the application makes direct use of all three packages.
Fig.1
application
java.lang
java.awt
cs101.canvas
Java VM
Operating System
Hardware
Basically,
we group a bunch of classes and interfaces together and give
them a name. Then, we begin to think of them as a unit,
rather than a bunch of separate classes.
Protection-Suppose we have some classes that we want
to be publicly used (outside our implementation by
other programmers),
but there are other classes we want used only within
our implementation(such as a ListItem class use be a public
LinkedList class)
Using Packages we can choose which classes may be used
outside the package,
and which ones can't.
We can even say which classes can be extended outside the
package and which methods can be overridden.
Convenience-
Provides a way to manage large software projects.
People agree on what the packages will provide, and
different programmers can write to them.
Provides a way to augment the language withouth
replacing it
Name Space Control- Two classes can have the same
name,
provided they are in different packages.
So, different programmers don't have to be concerned about
using names already used in other packages.
Choose a name for the package (all lower case letters)
Create a new directory (folder) with that name
for each classe or interface that you want to be part of
the package,
Create a .java file in the directory you created
put the line: package xxx;
at the top of the file (first non-comment
line)
Note: Multiple classes can exist in one file,
and all of them will be part of the package.
Only one class in a file can be public,
and the file must have the same name as that class.
Directories may be nested to create "subpackages".
For example,
to create the canvas package inside the cs101
package we:
created a folder called canvas inside the
cs101 folder
wrote the line: package cs101.canvas;
at the top of each file.
made sure that each file had at most one public
class and the file had the same name.
To use a class or interface from a package,
you can either:
give its fully qualified name as in: screen = new cs101.canvas.CS101Canvas();
OR
import the class or interface at the top of the file,
such as: import cs101.canvas.CS101Canvas;
and then you can use just the class name: screen = new CS101Canvas();
OR
import all the classes and interfaces from the
package as in: import cs101.canvas.*
and then you can use any class in the package by its name,
as in: screen = new CS101Canvas(); screen.add(new Rect(10,10,50,50));
How Java finds class files:
The Compiler refers to a list of directory names
(seperated by semicolons) called CLASSPATH, to find out
where you want it to look for class files. For example;
CLASSPATH = .;C:Cafe\Java\Lib
Here the . means the current working directory and the
second item (C:\Cafe\Java\Lib) is another directory to
search from.
Java expects that the directory structure matches the
package names inside of the directories in the CLASSPATH
list.
What happens if you import two classes with the same
name?
Depending onf the CLASSPATH, Java may
find the "wrong" one first, and it will complain, for example,
that the method you want to call on that object is not
available, or there's no such constructor. (The error message
may not tell you there's a name conflict.)
To disambiguate in this situation,
use the fully qualified class name.
Each class can either be public, meaning anyone can create one,
or "friendly",
meaning it can be instantiated only by methods of classes in the package.
Any of the 4 pretection levels can be chosen for any
instance
variable (data member),
method,
or class variable (static variable).
The following table summarizes what they imply:
access is available to:
public
proteted
default
private
All Classes
X
All Subclasses
X
X
Classes in the Same Package
X
X
X
The Class Itself
X
X
X
X
Note:Within a project,
all classes are considered to be in the same package (i.e.,
anything not imported is together in the "default package")
When I'm creating a package,
how do I decide which level of protection is appropriate?
Short Answer: Try to limit access as much as you can
without preventing reasonable use.
Long Answer:
Suppose you're creating a casino package that could
be used by programmers wanting to write applications for
games of chance.
In your package, you might provide:
Dice - that could be rolled
Cards - Ace through King in 4 suites plus Jokers
Decks of Cards - That can be shuffled and dealt
Wheels with labeled & colored pieces - that can be
spun
Card Hands - That hold some number of cards
Slot Machines - The containg collections of
wheels
...
At first,
it may sem like all classes should be public,
but what we listed here are the things we would expect the
user of the package to want (those should be
public).
But,
there will be other classes (such as,
perhaps,
a ListItem class for a circular list) that are part of the
internal representation of the public classes.
These internal items should not be public for two
reasons:
The users doesn't care about them,
so making them public just clutters up the user's view
of the package (the API)
Making them public ties your hands.
It can prevent you from making changes to the internal
representation later,
since users of the package may depend on those classes
being there.
So,
the rule of thumb for classes is:
If the user of the package needs it,
make it public,
but if its part of the internal representation,
keep it at the default ("package") level.
What about methods and instance variables?
The reasoning is similar, but there are more protection levels
to choose from.
Here's a rule of thumb for methods & instance variables:
if (access from outside this class could falsify a
representation invariant){
make it private so it's accessible only by this
class.
for variables,
control external access using accessor/mutator (get/set)
methods.
(Note: Most of the time, instance variable should be
private.)
}
else if (access is required by the package user){
make it public so it's part of the API
}
else if (access would be useful for subclasses, and would
not expose the represenatation to overly restrict future
implementations){
make it protected so subclasses can use/override it
}
else{
use the default ("friendly" or "package") protection
}
For example,
in the casino package,
what would you do with...
the method in roll() in the Dice Class? public (part
of API)
the instance variable numCardsLeft in Deck Class?
private (with public "get" accesor)
the method next() in the class ListOfCards?
package (assuming ListOfCards is not public & only
deck uses it.)
the instance variable suit in class Card?
private (wouldn't want it changed) OR public final
because you don't want to change it.
Final can also be used in conjunction with protection.
if a class is final,
you can't extend it & all its methods are automatically final.
if a method is final,
you can't override it.
Also,
when a method is final,
the compiler can "inline" it,
meaning that it puts the body of the method in place of the call to
avoid the runtime overhead involved in creating an activation
record & copying parameter values (but this is a bad idea if the
method is large because the class files get large).