Skip to main content

Java Tech: The Sweet Song of the BlueJ, Part 1

July 21, 2005

{cs.r.title}









Contents
What is BlueJ?
Installing BlueJ
Touring the GUI
BlueJ by Example
Conclusion
Resources
Answers to Previous Homework

I recently discovered a Java product called "http://www.bluej.org/">BlueJ. This product, symbolized by the
image of a blue jay, is used to teach object orientation to
students. In contrast to the harsh-sounding blue jay (which happens
to be a member of the crow family), BlueJ is anything but harsh.
This simple yet powerful product presents a short learning curve,
which is ideal for students.

Welcome to the first installment in a two-part series that
explores BlueJ. This article introduces the product, reveals its
reason for being (Java instructors, take note), shows how to install
BlueJ, and takes a tour of BlueJ's GUI. The article climaxes with
an example that illustrates several BlueJ features.

Note: This series is based on BlueJ version 2.0.4 and J2SE 5.0
running on the Windows 98 SE platform.

What is BlueJ?

BlueJ is an integrated Java environment that has been
designed to teach object orientation with the Java language. BlueJ
is based on the earlier Blue system, a programming language and
integrated environment. BlueJ, an almost identical environment to
Blue, replaces the Blue language with Java.

BlueJ provides a project manager and an editor. It relies upon
an installed Java 2 Standard Edition software development kit for
compilation, debugging, and other facilities. Tools are fully
integrated in BlueJ: compilation from within the editor, compiler
error message display in the editor, setting breakpoints in the
editor, and so on.

BlueJ was developed to provide an appropriate environment for
teaching object-orientation concepts to students. Unlike many other
environments, BlueJ emphasizes classes and objects as its basic
units of interaction. Students are not required to learn Java's
public static void main(String [] args) method, or
worry about input/output prior to creating and interacting with
objects: BlueJ takes care of those tasks on behalf of the student.
Regarding main(), BlueJ's developers believe that
introducing students to that method first is problematic. Why begin
teaching object orientation by introducing a method that is
essentially procedural? The BlueJ team discovered that this
approach only confuses students, who must also learn about arrays
right from the start. They found that it was better to first focus
on classes and objects, and introduce the main()
method, input/output, and arrays after the student becomes more
comfortable with Java.

BlueJ is easy to use; students can begin working with BlueJ
without needing a lengthy introduction to the environment. BlueJ
lets students visually and interactively create classes and
interconnect them. Students can then instantiate objects from those
classes, invoke methods, specify arguments to those methods via
dialogs, view return values via dialogs, and visually inspect
object state. This product is freely available, a benefit to
students who cannot afford costly licenses (BlueJ cannot be sold
for profit).

BlueJ originated at Monash University in Melbourne, Australia. It
is currently being maintained as a joint project among Deakin
University, the University of Kent, and the University of Southern
Denmark.

Installing BlueJ

BlueJ is available for Windows, the Mac OS, Linux/Unix, and other
operating systems. Regardless of the operating system, J2SE 1.4 or
higher must be installed. Because BlueJ relies on tools made
available via the J2SE SDK, installing only the J2SE JRE is not
sufficient.

For Windows platforms, the BlueJ distribution is contained in
file bluejsetup-xxx.exe, where
xxx is a version number. For example, the BlueJ
version 2.0.4 distribution is contained in
bluejsetup-204.exe.

The installer portion of the Windows BlueJ distribution lets you
select the directory into which to install BlueJ. It also presents
the option to install a shortcut into the Start menu and on the
desktop. When the installer completes, you'll find
bluej.exe in the installation directory. This program
starts BlueJ.

When BlueJ first runs, it searches for a J2SE 1.4 or higher SDK.
If it finds more than one version, BlueJ presents its BlueJ
Launcher dialog box, which lets you select the desired SDK. If
BlueJ isn't able to find a suitable SDK, this dialog box lets you
search for the SDK.

After installing BlueJ with a specific J2SE SDK, you can change
to another SDK version by including bluej.exe's
/select command-line option the next time you run that
program. In response, the BlueJ Launcher dialog box appears.

Note: You can install different versions of BlueJ and associate
a different installed version of the J2SE SDK with each BlueJ
version. For example, you can associate BlueJ 2.0.1 with J2SE 1.4.2
and associate BlueJ 2.0.4 with J2SE 5.0.

Touring the GUI

BlueJ manages Java-based projects. The current project is
revealed in its main window. In Figure 1, the main window
presents people--an example project that ships with
BlueJ--as the current project.

BlueJ's main window identifies the people project

Figure 1: BlueJ's main window identifies the people
project

The main window divides into five sections: menu bar, project
tool bar, class diagram, object bench, and message area. The menu
bar offers Project, Edit, Tools, View, and Help menus:

  • Project provides menu items that create a new project,
    open an existing project, save the current project, quit BlueJ, and
    more. For example, I selected Open Project... to open the example
    people project shown in Figure 1.
  • Edit provides menu items that introduce new classes into
    the current project, introduce new dependencies between classes,
    remove classes and dependencies, and more.
  • Tools provides menu items that compile all uncompiled
    classes in the current project, compile only the selected class,
    set preferences, and so on.
  • View provides menu items that show or hide dependencies,
    show or hide the debugger, and more.
  • Help provides menu items that show an about box, check
    for a new version of BlueJ, take you to a BlueJ tutorial, and so
    forth.

The project tool bar, located on the left side of the main
window and just below the menu bar, consists of four buttons that, respectively, introduce new classes into the current project,
introduce "extends" or "implements" dependencies between classes,
introduce "uses" dependencies between classes (for example, a
Library class uses a Book class by
implementing an array of Book objects), and compile
the entire project.

The class diagram, on the right side of the project tool bar,
graphically displays the current project. It presents a project
description note icon, class icons, and dependency arrows:

  • The project description note icon (in the upper-left corner)
    describes the current project. When creating a new project,
    double-click the icon to enter information about the project,
    including its author and how to run the project. This helps others
    understand your project and how to work with it.
  • Class icons identify classes and interfaces (which BlueJ
    regards as a special kind of class). The upper portion of the icon
    presents the class name. Abstract classes and interfaces are
    revealed by <<abstract>> or
    <<interface>> just above the name. The
    icon of the current class (that is, the class that will be compiled
    when you choose Compile Selected from the Tools menu) is identified
    with a darker border and a pair of diagonal stripes in the
    lower-right corner of its icon. If a class has not been compiled,
    the entire lower-right area consists of diagonal stripes.
  • Dependency arrows reveal relationships between classes. Solid
    lines with hollow arrow heads indicate either "extends"
    relationships (where the arrow points to the superclass) or
    "implements" relationships (where the arrow points to the
    interface). In Figure 1, two solid lines reveal "extends"
    relationships between Staff and Person,
    and between Student and Person.
    Person is the superclass. Dashed lines indicate "uses"
    relationships. Each class pointed to by the arrow is used by the
    class on the other end of the dashed line. For example, Figure 1
    shows that Person is used by Database. In
    other words, Database references Person
    in its source code.

Right-click the mouse on a class icon and a pop-up menu appears.
This menu offers various options, including compilation. If a
class's source code has not been compiled, you can compile that
source code by choosing Compile from the pop-up menu.

The object bench, toward the bottom of the main window,
identifies various objects that have been created. Objects are
created by right-clicking a compiled class's icon, selecting one of
the "new" constructor menu items from the pop-up menu, and
responding to dialogs that let you name the object and (if
appropriate) pass arguments to the constructor. Figure 1 shows a
single staff1 object icon on the object bench. The
object represented by that icon was created by choosing the top
menu item from the pop-up menu.

A single-line message area appears below the object bench. As
you work with BlueJ, various messages appear in this area.







BlueJ by Example

Let's use BlueJ to construct a simple payroll application. This
application introduces several BlueJ features and will get us
comfortable working in this Java environment.

Our payroll application will consist of the abstract class
Employee, the concrete subclasses CEO and
Salesperson, and the concrete driver class
RunPayroll. Although this latter class provides a
main() method for generating a payroll, we'll create
and interact with CEO and Salesperson
objects prior to looking at RunPayroll.

Start BlueJ. Before we introduce classes, we need a project.
From the Project menu, select New Project. A New Project
dialog box appears. Choose an appropriate directory that will
contain the project directory, and enter payroll as
the project/directory name.

The main window's title bar identifies payroll as
the current project. Except for the project description note icon,
the class diagram is empty. If you examine the payroll
directory, you will find two files: bluej.pkg and
README.TXT. The first file contains project settings
and the second file contains a template for documenting the
project.

We should document the project, to assist people wanting to use
our project, before introducing any classes. That way, we won't
forget to do so later. Double-click the project description note
icon and, via the resulting editor window, enter the project title,
project purpose, project version or date, instructions for starting
the project, project authors, and additional user instructions.
Figure 2 reveals the documentation I've chosen.

Document a project to help others learn about and use that project

Figure 2: Document a project to help others learn about and use
that project

The editor window presents a changed/saved indicator in the
lower-right corner. This indicator lets you know if there are
changes that need to be saved. You can periodically save changes
(while performing a lengthy edit) by selecting Save from the
Class menu. For now, exit the editor by selecting Close from
the Class menu, or by clicking the X button on the right side of
the title bar. In response, the editor automatically saves
changes.

We're ready to introduce our first class:
Employee. Click the New Class... button on the
project tool bar. A Create New Class dialog box appears. Enter
Employee in the dialog box's Class Name field. Also,
select the Abstract Class radio button in the Class Type group.
Figure 3 presents this dialog box with our choices.

The Create New Class dialog box lets you choose a class name and a class type

Figure 3. The Create New Class dialog box lets you choose a
class name and a class type

After clicking the OK button, an Employee icon, with
<<abstract>> above its name, appears in
the class diagram. Because we next need to enter source code into
the Employee class, right-click this icon and select
Open Editor from the pop-up menu, or double-click that icon. Either
way, Figure 4 shows the resulting editor window with a class
template for Employee.

Class templates provide skeletal source code for classes
Figure 4. Class templates provide skeletal source code for
classes

Employee's class template provides skeletal source
code that must be modified. Key in the source code below (making
appropriate changes to the skeletal source code) and then exit the
editor.

[prettify]/**
 * Abstract class Employee - the superclass for
 * CEO, Salesperson, and so on.
 * 
 * @author (Jeff Friesen)
 * @version (1.0)
 */

public abstract class Employee
{
   // employee name
    
   private String name;

   /**
    * Construct an employee.
    * 
    * @param name employee name
    */

   public Employee (String name)
   {
       this.name = name;
   }

   /**
    * Retrieve the employee's name.
    * 
    * @return employee's first and last names
    */

   public String getName ()
   {
       return name;
   }
    
   /**
    * Calculate employee's payment.
    * 
    * @return payment owed to employee
    */

   public abstract double payment ();
}
[/prettify]






For our purposes, an Employee is nothing more than
a name. This class is abstract to reflect the abstract
payment() method: different kinds of employees can be
paid in different ways (weekly, weekly plus commission, and so
on).

Right-click the Employee icon and select Compile from the
pop-up menu. A Compiling... message appears in the message area.
If a syntax error is detected, the editor window appears, that
window highlights the line containing the syntax error, and the
syntax error is identified in the editor window's status area (at
the bottom of the window). For example, if I lowercase
String in private String name;, I receive
the syntax error shown in Figure 5.

A class named string does not exist
Figure 5: A class named string does not
exist

Students learning Java will probably have trouble understanding
syntax errors. To help them in this situation, BlueJ's editor
window provides a "?" button. Click that button and a Message
dialog box appears. That dialog box provides further information
about the nature of the syntax error. The Message dialog box in
Figure 6 suggests that a class name may have been incorrectly
spelled.

The Message dialog box helps students more quickly discover the cause of a syntax error

Figure 6: The Message dialog box helps students more quickly
discover the cause of a syntax error

Fix the error, close the editor, and recompile. If there are no
more errors, a "Compiling...Done" message appears in the message
area. Furthermore, the diagonal stripes (apart from the two
diagonal stripes that indicate the current class) disappear from
the lower half of the compiled class's icon.

There's not much we can do with an abstract class. Therefore,
we'll create a CEO class and connect it to
Employee:

  • Click the project tool bar's New Class... button. From the
    Create New Class dialog box, enter CEO in the Class
    Name text field. Make sure the default Class radio button is
    selected prior to clicking OK. A CEO class icon appears to the
    right of the Employee class icon in the class diagram.
  • Select CEO and drag it below Employee. Then click the project
    tool bar's solid arrow button. The message area tells you to select
    the subclass. Click CEO. The message area next tells you to select
    the superclass. Click Employee. A solid arrow pointing from the CEO
    subclass to the Employee superclass appears.

After drawing the arrow, BlueJ makes this connection in
CEO's source code, as shown in Figure 7.

Employee CEO class hierarchy

Figure 7. The Employee/CEO class
hierarchy has been established through

extends
Employee

As with Employee, CEO's class template
provides skeletal source code that must be modified. Double-click
the CEO icon, key in the source code below (making the appropriate
changes to the skeletal source code), and then exit the editor.

[prettify]/**
 * CEO describes a chief executive officer. This
 * employee receives a salary based on a weekly
 * rate.
 * 
 * @author (Jeff Friesen) 
 * @version (1.0)
 */

public class CEO extends Employee
{
   // CEO weekly salary
        
   private double weeklySalary;

   /**
    * Construct a CEO.
    * 
    * @param name CEO's name
    * @param weeklySalary CEO's weekly salary
    */

   public CEO (String name, double weeklySalary)
   {
       super (name);
       setWeeklySalary (weeklySalary);
   }

   /**
    * Establish the CEO's weekly salary.
    * 
    * @param weeklySalary payment owed to CEO each
    *        week
    */

   public void setWeeklySalary
               (double weeklySalary)
   {
       this.weeklySalary = weeklySalary;
   }

   /**
    * Calculate CEO's payment.
    * 
    * @return payment owed to CEO each week
    */

   public double payment ()
   {
       return weeklySalary;
   }
}
[/prettify]






Compile this class's source code. Assuming compilation succeeds,
let's create a CEO object from our compiled
CEO class. We can then test its methods to make sure
that everything works. Right-click the CEO icon and select the "new
CEO(String name, double weeklySalary)" constructor menu item, shown
in Figure 8.

A compiled class's constructors appear at the top of its pop-up menu

Figure 8. A compiled class's constructors appear at the top of
its pop-up menu

In response to that menu item, the Create Object dialog box
appears. Enter everything shown in Figure 9 (including the double
quotes around John Doe) and click OK.

The Create Object dialog box lets you name an object and specify arguments for its constructor

Figure 9: The Create Object dialog box lets you name an object
and specify arguments for its constructor

A theBoss object icon appears on the object bench. Right-click
that icon. Figure 10 reveals a menu from which you can invoke
inherited methods, invoke CEO's payment()
and setWeeklySalary() methods, inspect object state,
and remove the object.

An object icon's pop-up menu lets you invoke that object's methods, inspect its state, and more

Figure 10. An object icon's pop-up menu lets you invoke that
object's methods, inspect its state, and more

Let's invoke the payment() method, by selecting the
"double payment()" menu item. BlueJ runs that method and displays
its return value in a Method Result dialog box. As Figure 11
illustrates, that value is 2000--the weekly salary.

The Method Result dialog box displays a method's return value
Figure 11. The Method Result dialog box displays a method's
return value

The Method Result dialog box presents Inspect and Get
buttons for inspecting a returned object and getting a new object,
based on the returned object's type to the object bench. Both
buttons are disabled because they make no sense in relation to
primitive types, such as double. Close the dialog
box.

Select the "inherited from Employee" menu item (see Figure 10)
followed by the "String getName()" menu item from the resulting
submenu. This executes the getName() method in the
Employee portion of our theBoss object.
Figure 12 reveals the expected "John Doe" string.

The Method Result dialog box no longer disables the Inspect and Get buttons

Figure 12. The Method Result dialog box no longer disables the
Inspect and Get buttons

Unlike in the previous Method Result dialog box, the Inspect
and Get buttons are enabled. We can use them to inspect or get a
new "John Doe" String object. Let's
inspect the object by clicking Inspect. Figure 13 shows the
resulting Object Inspector dialog box.

The Object Inspector dialog box displays the values in an object's instance fields

Figure 13. The Object Inspector dialog box displays the values
in an object's instance fields

In addition to presenting instance field values, the Object
Inspector dialog box provides a "Show static fields" button. Click
this button to view the values of a class's static fields (which
are shared by all objects created from that class). Because
String contains no static fields, don't count on
seeing them.

The Object Inspector dialog box presents reference field values
differently than the values of primitive type fields: curved arrows
indicate references. Double-click the arrow or click the Inspect
button (assuming that private char [] value is
highlighted) to inspect the array of characters object. Figure 14
presents a partial view of that object.

A partial view of the array of characters object
Figure 14. A partial view of the array of characters
object







Finally, let's take a look at the state of our
theBoss object. Select the Inspect menu item from
the pop-up menu previously shown in Figure 10. Figure 15's Object
Inspector dialog box reveals the contents of theBoss's
instance fields.

The complete state of our theBoss object

Figure 15. The complete state of our theBoss
object

Now that we've constructed the Employee and
CEO portions of our payroll application, let's turn
our attention to Salesperson. Introduce a Salesperson
icon into the class diagram and connect that icon to the Employee
icon. You've already seen how to do this with the CEO icon. Now
open the editor by double-clicking the Salesperson icon and enter
the source code below:

[prettify]/**
 * Salesperson describes an employee that sells
 * the company's products. This employee receives
 * a salary based on a weekly rate and a
 * commission for each sold product.
 * 
 * @author (Jeff Friesen) 
 * @version (1.0)
 */

public class Salesperson extends Employee
{
   // salesperson weekly salary
    
   private double weeklySalary;
    
   // salesperson commission
    
   private double commission;
    
   // number of sold products
    
   private int numProductsSold;
    
   /**
    * Construct a Salesperson.
    * 
    * @param name salesperson's name
    * @param weeklySalary salesperson's weekly
    *        salary
    * @param com salesperson's commission for
    *        each sold product
    * @param nsp number of sold products
    */

   public Salesperson (String name,
                       double weeklySalary,
                       double com, int nsp)
   {
       super (name);
       setWeeklySalary (weeklySalary);
       setCommission (com);
       setNumSoldProducts (nsp);
   }

   /**
    * Establish the salesperson's weekly salary.
    * 
    * @param weeklySalary payment owed to
    *        salesperson each week
    */
    
   public void setWeeklySalary
               (double weeklySalary)
   {
       this.weeklySalary = weeklySalary;
   }
    
   /**
    * Establish the salesperson's commission.
    * 
    * @param com amount of additional money
    *        salesperson receives for each sold
    *        item
    */    
    
   public void setCommission (double com)
   {
       commission = com;
   }

   /**
    * Establish the number of sold products.
    * 
    * @param nsp number of sold products
    */    
   
   public void setNumSoldProducts (int nsp)
   {
       numProductsSold = nsp;
   }
    
   /**
    * Calculate salesperson's payment.
    * 
    * @return payment owed to salesperson each
    *         week
    */
    
   public double payment ()
   {
       return weeklySalary + commission *
              numProductsSold;
   }
}
[/prettify]

Compile Salesperson, create an object from this
class, invoke methods, and inspect object state. This exercise will
reinforce what you've previously learned.

We have almost everything we need for our payroll application.
The final piece is a RunPayroll class whose
main() method drives the application. That class's
source code appears below.

[prettify]/**
 * Generate the weekly payroll for all employees.
 * 
 * @author (Jeff Friesen) 
 * @version (1.0)
 */

public class RunPayroll
{
   public static void main (String [] args)
   {
       Employee [] employees =
       {
          new CEO ("John Doe", 2000),
          new Salesperson ("Jane Doe", 600, 50,
                           20)
       };

       for (int i = 0; i &lt; employees.length; i++)
            System.out.println (employees [i].
                                getName () +
                                " makes " +
                                employees [i].
                                payment () +
                                " this week.");
   }
}
[/prettify]

RunPayroll references Employee,
CEO, and Salesperson. This suggests a
"uses" relationship between RunPayroll and these
classes. After creating a RunPayroll icon, employ the dashed-arrow
button on the project tool bar to introduce three separate dashed
arrows into the class diagram, where each arrow points from
RunPayroll to each of the other class icons. Enter the above source
code into RunPayroll and compile that class. Figure 16
shows the resulting class diagram.

Dashed arrows identify RunPayroll's referenced classes

Figure 16. Dashed arrows identify RunPayroll's
referenced classes

Figure 16 also shows a pop-up menu resulting from a right-click
on the RunPayroll icon. From that menu, select the "void
main(String [] args)" menu item. You are greeted by Figure 17's
Method Call dialog box.

The Method Call dialog box lets you pass arguments to methods
Figure 17. The Method Call dialog box lets you pass arguments to
methods

We don't have any String arguments to pass to the
main() method. If we did, we would specify those
arguments as a comma-delimited list between the brace characters.
Click the OK button instead. BlueJ's terminal window appears.
According to Figure 18, that window reveals our payroll
application's output.

BlueJ's terminal window displays payroll output
Figure 18. BlueJ's terminal window displays payroll
output







Conclusion

Are you planning to teach Java? Consider using BlueJ. This
integrated Java environment has been designed to teach object
orientation with the Java language. BlueJ emphasizes classes and
objects right from the start; it doesn't confuse students by first
focusing on the procedural main() method, arrays, and
input/output.

BlueJ is easy to install and run. It requires an installed J2SE
SDK (version 1.4 or higher). If you ever need to switch from one
SDK version to another version, include bluej.exe's
/select command-line option when starting BlueJ.

BlueJ offers a simple yet capable GUI divided into menu bar,
project tool bar, class diagram, object bench, and message area. We
made extensive use of this GUI as we developed and tested an
example payroll application.

I have some homework for you to accomplish:

  • Use BlueJ to add a FactoryWorker class that
    subclasses Employee. Factory workers receive a payment
    based on a fixed amount per item they create. For example, a worker
    receives five dollars for each created item. If the worker creates
    100 items in a week, the worker's payment is 500 dollars. Extend
    RunPayroll to include FactoryWorker.

Next time, "Java Tech" completes this series by investigating
BlueJ's debugging, documentation generation, and JAR-packaging
capabilities. You also learn how to configure BlueJ and discover a
useful feature known as the code pad.

Resources

Answers to Previous Homework

The "http://today.java.net/pub/a/today/2005/05/17/lessons.html">previous
"Java Tech" article
presented you with some challenging homework
on language lessons. Let's revisit that homework and investigate
solutions.

  1. Is it okay for the clone() method to invoke an
    overridable method?

    It is not okay for the clone() method to invoke an
    overridable method, because the overriding method might modify
    object state while the clone() method executes, and
    these changes could damage either the object being cloned, the
    cloned object, or both objects. Let us see how this damage might
    occur, beginning with an examination of the classes below:

    [prettify]class Parent implements Cloneable
    {
       public Parent clone ()
         throws CloneNotSupportedException
       {
          System.out.println ("Superclass clone() " +
                              "method invoked");
    
          someMethod ();
    
          return (Parent) super.clone ();
       }
    
       void someMethod ()
       {
          System.out.println ("parent someMethod() " +
                              "invoked");
       }
    
    }
    
    class Child extends Parent
    {
       ArrayList&lt;String&gt; al;
    
       Child ()
       {
          al = new ArrayList&lt;String&gt; ();
    
          al.add ("One string");
       }
          
       public Child clone ()
         throws CloneNotSupportedException
       {
          System.out.println ("Subclass clone() " +
                               "method invoked");
    
          System.out.println ("ArrayList size " +
                              "before " +
                              "super.clone() = " +
                              al.size ());
    
          Child c = (Child) super.clone ();
    
          System.out.println ("ArrayList size " +
                              "after " +
                              "super.clone() = " +
                              al.size ());
    
          return c;
       }  
    
       void someMethod ()
       {
          System.out.println ("child someMethod() " +
                              "invoked -- clearing " +
                              "array");
          al.clear ();
       }
    }
    [/prettify]

    Child's clone() method outputs the
    size of an ArrayList, invokes
    super.clone(), and then outputs the
    ArrayList's size once more. Each output operation
    symbolizes work needed to create a clone. The
    super.clone() method call invokes
    Parent's clone() method. In turn, that
    method invokes the overridable someMethod().
    Child's version of that method clears the
    ArrayList. If we were to execute
    Child c1 = new
    Child ();
    , followed by Child c2 = c1.clone ();,
    we would see the output below. This output indicates that
    Child's state has changed, as a result of the
    super.clone() method call.

    [prettify]Subclass clone() method invoked
    ArrayList size before super.clone() = 1
    Superclass clone() method invoked
    child someMethod() invoked -- clearing array
    ArrayList size after super.clone() = 0
    [/prettify]

    This example is trivial. Perhaps you might share your own
    experiences with failure caused when a superclass
    clone() method invokes an overridable method.

  2. Should interfaces be used to only export constants (i.e., no
    methods are part of such interfaces, only constants)? Although I
    didn't discuss constant interfaces in this article, think of it as
    another lesson that you should know.

    Interfaces should not be used to only export constants, because
    that usage violates the purpose for interfaces--they are types
    that describe auxiliary capabilities of the classes that implement
    them. For example, java.util.Iterator is an interface
    type whose implementing classes serve as iterators, in addition to
    their main reasons for existence. Constant interfaces have nothing
    to do with types; they exist to save time entering source code.
    Fewer keystrokes are needed to refer to an interface-exported
    constant (only the constant name needs to be entered, after
    implementing the interface once) than a class-exported constant
    (the class name, a period character, and the constant name need to
    be entered each time the constant must be specified).

    Dependence on constant interfaces can lead to maintenance
    problems. As time passes, a class will evolve; one or more of the
    interface's constants may no longer be required. However, the class
    still needs to implement the interface (including all of the
    constants), to maintain binary compatibility. This can lead to
    confusion. Also, we end up polluting the class's namespace and the
    namespaces of any subclasses with the constants. This gets really
    bad if we create a single interface that conveniently declares all
    of our constants in one place. Imagine hundreds of constant names
    polluting the namespace.

    J2SE 5.0 provides a better alternative to constant interfaces:
    static imports. This language feature lets you refer to the static
    members of a class without having to qualify those members with the
    class name. Consider the following static imports:

    [prettify]import static java.lang.Math.*;     // import all static members
    
    // or, to import specific members only
    
    import static java.lang.Math.PI;    // import static member PI only
    import static java.lang.Math.cos(); // import static member cos() only
    [/prettify]

    You can now specify sin() instead of
    Math.sin(), PI instead of
    Math.PI, and cos() instead of
    Math.cos(). Constant interfaces have gone the way of
    the dinosaur.

width="1" height="1" border="0" alt=" " />
Jeff Friesen is a freelance software developer and educator specializing in Java technology. Check out his site at javajeff.mb.ca.
Related Topics >> Education   |   Programming   |