A superclass defines common behavior for related subclasses. An interface can be used to define common behavior for classes (including unrelated classes). You can use the java.util.Arrays.sort method to sort an array of numbers or strings. Can you apply the same sort method to sort an array of geometric objects? In order to write such code, you have to know about interfaces. An interface is for defining common behavior for classes (including unrelated classes). An interface is a class-like construct that contains only constants and abstract methods.
In many ways an interface is similar to an abstract class, but its intent is to specify common behavior for objects of related classes or unrelated classes. For example, using appropriate interfaces, you can specify that the objects are comparable, edible, and/or cloneable.
To distinguish an interface from a class, Java uses the following syntax to define an interface:
modifier interface InterfaceName {
/** Constant declarations */
/** Abstract method signatures */
}
Here is an example of an interface:
public interface Edible {
/** Describe how to eat */
public abstract String howToEat();
}
An interface is treated like a special class in Java. Each interface is compiled into a separate bytecode file, just like a regular class. You can use an interface more or less the same way you use an abstract class. For example, you can use an interface as a data type for a reference
variable, as the result of casting, and so on. As with an abstract class, you cannot create an instance from an interface using the new operator.
You can use the Edible interface to specify whether an object is edible. This is accomplished by letting the class for the object implement this interface using the implements keyword. For example, the classes Chicken and Fruit in the program below (lines 24, 43) implement the Edible interface. The relationship between the class and the interface is known as interface inheritance. Since interface inheritance and class inheritance are essentially the same, we will simply refer to both as inheritance.
package demo;
public class TestEdible {
public static void main(String[] args) {
Object[] objects = {new Tiger(), new Chicken(), new Apple()};
for(int i = 0; i < objects.length; i++) {
if(objects[i] instanceof Edible)
System.out.println(((Edible)objects[i]).howToEat());
if(objects[i] instanceof Animal) {
System.out.println(((Animal)objects[i]).sound());
}
}
}
}
abstract class Animal{
/** Return animal sound */
public abstract String sound();
}
class Chicken extends Animal implements Edible{
@Override
public String howToEat() {
return "Chicken: Fry it";
}
@Override
public String sound() {
return "Chicken: cock-a-doodle-doo";
}
}
class Tiger extends Animal{
@Override
public String sound() {
return "Tiger: RROOAAARR";
}
}
abstract class Fruit implements Edible{}
class Apple extends Fruit{
@Override
public String howToEat() {
return "Apple: Make apple cider";
}
}
class Orange extends Fruit{
@Override
public String howToEat() {
return "Orange: Make orange juice";
}
}
Tiger: RROOAARR
Chicken: Fry it
Chicken: cock-a-doodle-doo
Apple: Make apple cider
This example uses several classes and interfaces. Their inheritance relationship is shown in Figure below.
The Animal class defines the sound method (line 21). It is an abstract method and will be implemented by a concrete animal class.
The Chicken class implements Edible to specify that chickens are edible. When a class implements an interface, it implements all the methods defined in the interface with the exact signature and return type. The Chicken class implements the howToEat method (lines 26–28). Chicken also extends Animal to implement the sound method (lines 31–33).
The Fruit class implements Edible. Since it does not implement the howToEat method, Fruit must be denoted as abstract (line 43). The concrete subclasses of Fruit must implement the howToEat method. The Apple and Orange classes implement the howToEat method (lines 47, 54).
The main method creates an array with three objects for Tiger, Chicken, and Apple (line 6), and invokes the howToEat method if the element is edible (line 9) and the sound method if the element is an animal (line 12).
In essence, the Edible interface defines common behavior for edible objects. All edible objects have the howToEat method.
Since all data fields are public static final and all methods are public abstract in an interface, Java allows these modifiers to be omitted. Therefore the following interface definitions are equivalent: