Debugging TipsTopTalking to ActiveObjectsInterfaces

Interfaces

The collection of operations/methods that can be used from outside a class to interact with an object of the class is called the interface to the class. This explains why the topics "Interfaces" and "User Interfaces" have related names. "User Interfaces" are the mechanisms through which users can interact with the state of an entire program. "Interfaces" are the mechanisms through which one component (object) within a program can interact with another.

The interface of objects for a Java class can be concisely described by listing all of its methods and describing their parameters. That is why we ask you to include such information in your designs.

To illustrate the use of this new Java mechanism we will use the Tshirt class from our laundry sorter as an example.

The form of an interface specification is quite simple:

For example, here is an interface specification for the properties of the Tshirts used in our laundry sorter program.

// A piece of laundry of an arbitrary shape.
public interface Laundry {

      // Move the laundry relative to its current position
      // Parameter:
      //    xOffset - distance to move horizontally
      //    yOffset - distance to move vertically
      public void move(double xOffset, double yOffset);

      // Move the laundry to a specific position:
      //    x - x coordinate
      //    y - y coordinate
      public void moveTo(double x, double y);

      // Remove the laundry from the display
      public void hide();

      // Return true if the point is in the laundry
      // Parameters:
      //    pt - the point to test for containment
      public boolean contains(Location pt);

      // Set the color of the item:
        //      hue - the new color
      public void setColor(Color hue);

      // Return the color of the item.
      public Color getColor();
}

With this interface included in our program, we can now construct a more advanced version of the laundry sorter.

Demo: ShirtsAndPants

We hope that you noticed that, thanks to the use of a class definition, we had to change very little when we converted our initial laundry program (where the laundry items were just FilledRects) into our current, fancy Tshirt version. Basically, the only change required was that the declaration:

FilledRect item;
had to be replaced by a declaration of the form:
Tshirt item;
and to change the constructor used.

The code that manipulated the laundry (i.e. onMouseDrag, etc.) remained unchanged. Interfaces let us write even more flexible code.

Suppose we have two classes of laundry defined. Tshirts (as before) and something else like Pants. If they both contain all the methods listed in our Laundry interface, we can explicitly tell Java this in the headers of the class declarations:

      public class Tshirt implements Laundry ...

So long as we restrict ourselves to the methods defined by the Laundry interface, it doesn't matter what type of laundry we come up with in the future (maybe we want to add Wool Socks for the winter). We can continue to use any program that manipulates objects via the Laundry interface without changing it!

To tell Java that we want to use objects that implement the Laundry interface in our laundry sorter, we can replace the declaration of the item variable in the window controller with a declaration of the form:

Laundry item;

When we write a declaration, remember that we are telling Java what sort of object the name may be associated with. The declaration "Laundry item" tells Java that item may be associated with an object of any class that implements the Laundry interface.

So, Java will allows us to say either:

    item = new Tshirt( ... );
or
    item = new Pants( ... );

On the other hand, java will not allow us to say:

    item = new Laundry( ... );

This makes a lot of sense. In the specification of the interface Laundry, we did not include a constructor. That is because in order to construct an object, we need to know the details of how its state will be represented. The whole point of an interface, however, is to focus on the interface through which the state can be manipulated while ignoring the details of how the state is represented.

On the other hand, given that Java knows that "item" will only be associated with things that implement the Laundry interface, it will let us write commands like:

      item.moveTo(...);

Note that Java will not allow us to assign any object with the right methods to the "item" variable. In particular, even if the methods in the Laundry interface were a subset of those provided by FilledRects, we could not say:

      item = new FilledRect( ... );
since the declaration of the class FilledRect does not say:
      public class FilledRect implements Laundry {

      }

Also, note that we can use interface names as type names in parameter declarations.


Debugging TipsTopTalking to ActiveObjectsInterfaces