SUNY Geneseo, Department of Computer Science


Java Interfaces

by Doug Baldwin

An interface in Java is similar to a class, in that, like a class, an interface is a type that can be used to declare variables and parameters. For instance, if ExampleInterface is the name of an interface, then you could declare a variable v as

    ExampleInterface v;

The big difference between interfaces and classes is that an interface is solely a specification of the messages that an object responds to, without any methods for handling those messages, whereas a class typically provides methods for handling the messages it declares. Because an interface defines no methods, it does exactly what the informal term "interface" implies: define the interface between certain objects and their clients, but without defining any of the objects' implementations.

This document describes the basics of declaring and using interfaces, and says a little bit about when to use interfaces and when to use classes. Certain advanced features of interfaces are not covered here, but can be found in a Java reference manual.

Declaring an Interface

The syntax for declaring an interface is

    interface name {
        header1
        header2
        ...
    }

where name is the interface's name, and header1, header2, and so forth are method headers (without bodies).

For example, imagine various objects that act like counters, in that they respond to parameterless increment and decrement messages, a setValue message that takes an integer as its only parameter, and a parameterless getValue message that returns an integer. You could define an interface that describes these four messages thus:

    interface Counter {
        public void increment();
        public void decrement();
        public void setValue( int v );
        public int getValue();
    }

Note that the interface declaration says nothing about what these messages do, only what their names are, what parameters they take, and what type of value (if any) they return -- in other words, what a client needs to know to send the messages, and nothing more. Each message that these counters can handle is declared within the interface declaration with a header that is exactly like the header you would use to start a full method definition in a class, but none of these headers is followed by a body.

Using Interfaces

Because interfaces don't say how messages are handled, they are not sufficiently complete types to actually create objects from (to "instantiate"). For example, with the Counter interface shown above, you could not say

    Counter c = new Counter();    // INVALID CODE!

However, you can do two things with interfaces:

Typically, you will declare several classes that implement an interface (the first use of interfaces above). Once this is done, declaring variables or parameters with the interface (the second use) becomes a source of great flexibility, because any instance of any of the classes that implement the interface can be assigned to those variables and parameters.

Classes that Implement an Interface

A class that implements an interface is declared as follows:

    class name implements interface {
        class body
    }

where name is the name of the class, interface is the name of the interface that the class implements, and class body is a perfectly ordinary class body (i.e., a series of method definitions, member variable declarations, etc.)

For example, a class that represents integer counters that increment and decrement by one might be written as follows:

    class UnitCounter implements Counter {
        private int value;
        public UnitCounter() {
            value = 0;
        }
        public void increment() {
            value = value + 1;
        }
        public void decrement() {
            value = value - 1;
        }
        public void setValue( int v ) {
            value = v;
        }
        public int getValue() {
            return value;
        }
    }

This class provides complete methods for handling all of the messages mentioned in the interface it implements. Indeed, declaring a class as implementing some interface obliges the programmer to provide methods for each message declared in the interface. Also note, however, that the UnitCounter class provides features not mentioned in the Counter interface -- a constructor, a member variable, etc. This is perfectly legal, and entirely typical. Most classes that implement interfaces provide a great deal in addition to what the interface obliges them to provide.

A class can implement several interfaces. To declare a class that does this, simply list all the interfaces the class implements after the keyword implements, separated by commas. For example

    class FancyCounter implements Counter, ExampleInterface, WhizBangInterface, YetAnotherInterface {
        ...
    }

A class that implements multiple interfaces is, of course, obligated to provide methods for all the messages listed in any of the interfaces it implements.

Declaring Variables or Parameters with Interfaces

An interface name can be used just like a class name to declare a variable or parameter. For example

    Counter c;
    class SomeClass {
        ...
        public void someMethod( Counter x ) {
            ...
        }
    }

Declaring a variable or parameter in this manner tells the Java compiler that it is legal to send that variable or parameter any of the messages declared in the interface. Send these messages just like you would send messages to any other object. For example

    public void someMethod( Counter x ) {
        x.increment();
        ...
    }

As mentioned earlier, the only thing you cannot do is use new with the interface name to create a value to assign to one of these variables or parameters. However, you can assign them any instance of any class that implements the interface. For example

    Counter c = new UnitCounter();

Classes vs Interfaces

There are close similarities between classes and interfaces. Both define a set of messages that certain objects will handle. Implementing an interface is in many ways analogous to subclassing a class. These similarities between classes and interfaces can make it hard to decide whether to define a type as a class or as an interface.

Sometimes, the choice between class and interface will be dictated by the limitations of each. For example, if you want to instantiate a type, then that type has to be a class (since you can't instantiate an interface). If member variables are an important part of a type, then that type has to be a class (interfaces can't contain member variables). If you want other classes to be derived from multiple types, then those types have to be interfaces (since a class can have at most one superclass, but can implement many interfaces).

At a conceptual level, it may help you choose between making something a class versus making it an interface if you think of a class as defining what an object is, whereas an interface defines what an object acts like. Thus, if you want to declare a variable or parameter as storing objects that are a certain type of thing, create a class to use in these declarations. On the other hand, if you only need to say that a variable or parameter stores objects that act in certain ways (i.e., by handling certain messages), without concern for what they really are, create an interface to use in the declarations. For example, if Fish is a class, and Swimmer is an interface, then the declaration

    Fish f;

conceptually says that f is a fish, whereas the declaration

    Swimmer s;

says that s merely acts like something that swims -- perhaps by handling a swim message. The object stored in s could really be any kind of thing that acts in this way -- it could be a fish, it could be a boat, it could be a human athlete, etc.

This conceptual view of classes and interfaces highlights the fact that declaring something to be an instance of an interface is in many ways a less restrictive, more flexible, declaration than declaring it to be an instance of a class. For this reason, programs that contain many user-defined types will often define those types as interfaces wherever possible, and only use classes for types that must be directly instantiated.


Last Updated January 30, 2007

{CopyrightNotice}