Toolboxes, API's, and Packages
AS COMPUTERS AND THEIR USER INTERFACES have become easier to use, they have also become more complex for programmers to deal with. A simple console-style user interface can be programmed using just a few subroutines, for writing output to the console and for reading the user's typed replies. A modern graphical user interface, with windows, buttons, scroll bars, menus, text-input boxes, and so on, might make things easier for the user. But it forces the programmer to cope with a hugely expanded array of possibilities. The programmer sees this increased complexity in the form of great numbers of subroutines that are provided for managing the user interface, as well as for other purposes.
Someone who wants to program for Macintosh computers -- and to produce programs that look and behave the way users expect them to -- must deal with the Macintosh Toolbox, a collection of well over a thousand different subroutines. There are routines for opening and closing windows, for drawing geometric figures and text to windows, for adding buttons to windows, and for responding to mouse clicks on the window. There are other routines for creating menus and for reacting to user selections from menus. Aside from the user interface, there are routines for opening files and reading data from them, for communicating over a network, for sending output to a printer, for handling communication between programs, and in general for doing all the standard things that a computer has to do. Windows 95 and Windows 3.1 provide similar sets of subroutines for programmers to use.
The analogy of a "toolbox" is a good one to keep in mind. Every programming project involves a mixture of innovation and reuse of existing tools. A programmer is given a set of tools to work with, starting with the set of basic tools that are built into the language: things like variables, assignment statements, if statements, and loops. To these, the programmer can add existing toolboxes full of routines that have already been written for performing certain tasks. These tools, if they are well-designed, can be used as true black boxes: They can be called to perform their assigned tasks without worrying about the particular steps they go through to accomplish those tasks. The innovative part of programming is to take all these tools and apply them to some particular project or problem (word-processing, keeping track of bank accounts, processing image data from a space probe, Web browsing, computer games,...). This is called applications programming.
A software toolbox presents a certain interface to the programmer. This interface is a specification of what routines are in the toolbox, what parameters they use, and what tasks they perform. This information constitutes the API, or Applications Programming Interface, associated with the toolbox. The Macintosh API is a specification of all the routines available in the Macintosh Toolbox. A company that makes some hardware device -- say a card for connecting a computer to a network -- might publish an API for that device consisting of a list of routines that programmers can call in order to communicate with and control the device. Scientists who write a set of routines for doing some kind of complex computation -- such as solving "differential equations", say -- would provide an API to allow others to use those routines without understanding the details of the computations they perform.
The Java programming language is supplemented by a large, standard API. You've seen part of this API already, in the form of Math subroutines such as Math.sqrt(), the String data type and its associated routines as discussed in Section 2.8, and the System.out.print() routines. The standard Java API includes routines for working with graphical user interfaces, for network communication, for reading and writing files, and more. It's easy to think of these routines as being built into the Java language, but they are technically subroutines that have been written and made avaialble for use in any Java program.
Java is platform-independent. That is, the same program can run on platforms as diverse as Macintosh, Windows, UNIX, and others. The same Java API must work on all these platforms. But notice that it is the interface that is platform-independent; the implementation varies from one platform to another. A Java system on a particular computer includes implementations of all the standard API routines. A Java program includes only calls to those routines. When the Java interpretor executes a program and encounters a call to one of the standard routines, it will pull up and execute the implementation of that routine which is appropriate for the particular platform on which it is running. This is a very powerful idea.
Like all subroutines in Java, the routines in the standard API are grouped into classes. To provide larger-scaled organization, classes in Java can be grouped into packages. You can have even higher levels of grouping, since packages can also contain other packages. In fact, the entire standard Java API is implemented as one large package, which is named "java". The java package, in turn, is made up of several other packages, and each of those packages contains a number of classes.
One of the sub-packages of java, for example, is called "awt". Since awt is contained within java, its full name is actually java.awt. This is the package that contains classes related to graphical user interfaces, such as the Button class, which represents push-buttons on the screen that the user can click on, and the Graphics class, which provides routines for drawing on the screen. Since these classes are contained in the package java.awt, their full names are actually java.awt.Button and java.awt.Graphics. (I hope that by now you've gotten the hang of how this naming thing works in Java.)
The java package includes several other sub-packages, such as java.net, which deals with network communication, and java.applet, which implements the basic functionality of applets. The most basic package is called java.lang, which includes fundamental classes such as String and Math.
It might be helpful to look at a graphical representation of the levels of nesting in the java package, its sub-packages, the classes in those sub-packages, and the subroutines in those classes:
Let's say that you want to use the class java.awt.Button in a program that you are writing. One way to do this is to use the full name of the class. For example, you could say
to declare a variable named stopBttn whose type is java.awt.Button. Of course, this can get tiresome. If you say
at the very beginning of your program, before you start writing any class, then you can abbreviate the full name java.awt.Button to just the name of the class, Button. This would allow you to say just
to declare the variable stopBttn. (The only effect of the import statement is to allow you to use simple class names instead of full "package.class" names; you aren't really importing anything substantial.) There is even a shortcut for importing all the classes in a package. You can import all the classes from java.awt by saying
In fact, most Java programs begin with this line, and might also include lines such as "import java.net.*;" or "import java.io.*".
Because the package java.lang is so fundamental, all the classes in java.lang are automatically imported into every program. It's as if every program began with the statement "import java.lang.*;". This is why we have been able to use the class name String instead of java.lang.String, and Math.sqrt() instead of java.lang.Math.sqrt(). It would still, however, be perfectly legal to use the longer form of the names.
Programmers can create new packages. In fact, every class is part of a package. If a class is not specifically placed in a package, then it is put in something called the default package, which has no name. The Console class that I've been using in examples in these notes is in the default package. In projects that define large numbers of classes, it makes sense to organize those classes into one or more packages. It also make sense for programmers to create new packages as toolboxes that provide functionality and API's for dealing with areas not covered in the standard Java API. (And in fact such "toolmaking" programmers often have more prestige than the applications programmers who use their tools.)
[ Next Section | Previous Section | Chapter Index | Main Index ]