Interfaces

From Wikibooks, open books for an open world
Jump to: navigation, search

Inheritance Java Programming
Interfaces
Overloading Methods and Constructors
Navigate Classes and Objects topic: v  d  e )

An interface is an abstraction of class with no implementation details. For example, java.lang.Comparable is a standard interface in Java. You cannot instantiate an interface. An interface is not a class but it is written the same way. The first difference is that you do not use the class keyword but the interface keyword to define it. Then, there are fields and methods you cannot define here:

  • A field is always a constant: it is always public, static and final, even if you do not mention it.
  • A method must be public and abstract, but it is not required to write the public and abstract keywords.
  • Constructors are forbidden.

An interface represents a contract:

Computer code Code listing 4.14: SimpleInterface.java
  1. public interface SimpleInterface {
    
  2.     public static final int CONSTANT1 = 1;
    
  3.     int method1(String parameter);
    
  4. }
    

You can see that the method1() method is abstract (unimplemented). To use an interface, you have to define a class that implements it, using the implements keyword:

Computer code Code listing 4.15: ClassWithInterface.java
  1. public class ClassWithInterface implements SimpleInterface {
    
  2.     int method1(String parameter) {
    
  3.         return 0;
    
  4.     }
    
  5. }
    

A class can implement several interface, separated by a comma. Java interfaces behave much like the concept of the Objective-C protocol. It is recommended to name an interface <verb>able, to mean the type of action this interface would enable on a class. However, it is not recommended to start the name of an interface by I as in C++. It is useless. Your IDE will help you instead.

Interest[edit]

If you have objects from different classes that do not have common superclasses, you can't call a same method on them, even if the two classes implement a method with the same signature.

Computer code Code listing 4.16: OneClass.java
  1. public class OneClass {
    
  2.     public int method1(String parameter) {
    
  3.         return 1;
    
  4.     }
    
  5. }
    
Computer code Code listing 4.17: AnotherClass.java
  1. public class AnotherClass {
    
  2.     public int method1(String parameter) {
    
  3.         return 2;
    
  4.     }
    
  5. }
    
Warning Code section 4.16: Impossible call.
  1. public static void main(String[] args) {
    
  2.     doAction(new OneClass());
    
  3.     doAction(new AnotherClass());
    
  4. }
    
  5.  
    
  6. public void doAction(Object anObject) {
    
  7.     anObject.method1("Hello!");
    
  8. }
    

The solution is to write an interface that defines the method that should be implemented in the two classes as the SimpleInterface in the Code listing 4.14 and then the both class implement the interface as in the Code listing 4.15.

Example Code section 4.17: Interface use.
  1. public static void main(String[] args) {
    
  2.     doAction(new ClassWithInterface());
    
  3.     doAction(new AnotherClassWithInterface());
    
  4. }
    
  5.  
    
  6. public void doAction(SimpleInterface anObject) {
    
  7.     anObject.method1("Hello!");
    
  8. }
    

You can also have this interest using a common super class but a class can only inherit from one super class whereas it can implement several interfaces. Java does not support full orthogonal multiple inheritance. Java does not allow you to create a subclass from two classes. Multiple inheritance in C++ has complicated rules to disambiguate fields and methods inherited from multiple superclasses and types inherited multiple times. By separating interface from implementation, interfaces offer much of the benefit of multiple inheritance with less complexity and ambiguity. The price of no multiple inheritance is some code redundancy; since interfaces only define the signature of a class but cannot contain any implementation, every class inheriting an interface must provide the implementation of the defined methods, unlike in pure multiple inheritance, where the implementation is also inherited. The major benefit of that is that all Java objects can have a common ancestor. That class is called Object. When overriding methods defined in interfaces there are several rules to be followed:

  • Checked exceptions should not be declared on implementation methods other than the ones declared by the interface method or subclasses of those declared by the interface method.
  • The signature of the interface method and the same return type or subtype should be maintained when implementing the methods.
  • All the methods of the interface need to be defined in the class, unless the class that implements the interface is abstract.

Extending interfaces[edit]

Execution of this example on BlueJ.

An interface can extend several interfaces, similar to the way that a class can extend another class, using the extends keyword:

Computer code Code listing 4.18: InterfaceA.java
  1. public interface InterfaceA {
    
  2.   public void methodA();
    
  3. }
    
Computer code Code listing 4.19: InterfaceB.java
  1. public interface InterfaceB {
    
  2.   public void methodB();
    
  3. }
    
Computer code Code listing 4.20: InterfaceAB.java
  1. public interface InterfaceAB extends InterfaceA, InterfaceB {
    
  2.   public void otherMethod();
    
  3. }
    

This way, a class implementing the InterfaceAB interface has to implement the methodA(), the methodB() and the otherMethod() methods:

Computer code Code listing 4.21: ClassAB.java
  1. public class ClassAB implements InterfaceAB {
    
  2.   public void methodA() {
    
  3.     System.out.println("A");
    
  4.   }
    
  5.  
    
  6.   public void methodB() {
    
  7.     System.out.println("B");
    
  8.   }
    
  9.  
    
  10.   public void otherMethod() {
    
  11.     System.out.println("foo");
    
  12.   }
    
  13.  
    
  14.   public static void main(String[] args) {
    
  15.     ClassAB classAb = new ClassAB();
    
  16.     classAb.methodA();
    
  17.     classAb.methodB();
    
  18.     classAb.otherMethod();
    
  19.   }
    
  20. }
    

Doing so, a ClassAB object can be casted into InterfaceA, InterfaceB and InterfaceAB.

Test your knowledge

Question 4.2: Consider the following interfaces.

Computer code Question 4.2: Walkable.java
  1. public interface Walkable {
    
  2.     void walk();
    
  3. }
    
Computer code Question 4.2: Jumpable.java
  1. public interface Jumpable {
    
  2.     void jump();
    
  3. }
    
Computer code Question 4.2: Swimable.java
  1. public interface Swimable {
    
  2.     void swim();
    
  3. }
    
Computer code Question 4.2: Movable.java
  1. public interface Movable extends Walkable, Jumpable {
    
  2. }
    

List all the methods that an implementing class of Movable should implement.

Answer
  • walk()
  • jump()
Computer code Answer 4.2: Person.java
  1. public class Person implements Movable {
    
  2.     public void walk() {
    
  3.         System.out.println("Do something.");
    
  4.     }
    
  5.  
    
  6.     public void jump() {
    
  7.         System.out.println("Do something.");
    
  8.     }
    
  9. }
    

Question 4.3: Consider the following classes and the following code.

Computer code Question 4.3: ConsoleLogger.java
  1. import java.util.Date;
    
  2.  
    
  3. public class ConsoleLogger {
    
  4.     public void printLog(String log) {
    
  5.         System.out.println(new Date() + ": " + log);
    
  6.     }
    
  7. }
    
Computer code Question 4.3: FileLogger.java
  1. import java.io.File;
    
  2. import java.io.FileOutputStream;
    
  3.  
    
  4. public class FileLogger {
    
  5.   public void printLog(String log) {
    
  6.     try {
    
  7.       File file = new File("log.txt");
    
  8.       FileOutputStream stream = new FileOutputStream(file);
    
  9.       byte[] logInBytes = (new Date() + ": " + log).getBytes();
    
  10.  
    
  11.       stream.write(logInBytes);
    
  12.  
    
  13.       stream.flush();
    
  14.       stream.close();
    
  15.     } catch (Exception e) {
    
  16.       e.printStackTrace();
    
  17.     }
    
  18.   }
    
  19. }
    
Example Question 4.3: Common code.
  1. Object[] loggerArray = new Object[2];
    
  2. loggerArray[0] = new ConsoleLogger();
    
  3. loggerArray[1] = new FileLogger();
    
  4.  
    
  5. for (Object logger : loggerArray) {
    
  6.     // logger.printLog("Check point.");
    
  7. }
    

Change the implementation of the code in order to be able to uncomment the commented line without compile error.

Answer

You have to create an interface that defines the method printLog(String) and makes ConsoleLogger and FileLogger implement it:

Computer code Answer 4.3: Logger.java
  1. public interface Logger {
    
  2.     void printLog(String log);
    
  3. }
    
Computer code Answer 4.3: ConsoleLogger.java
  1. import java.util.Date;
    
  2.  
    
  3. public class ConsoleLogger implements Logger {
    
  4.     public void printLog(String log) {
    
  5.         System.out.println(new Date() + ": " + log);
    
  6.     }
    
  7. }
    
Computer code Answer 4.3: FileLogger.java
  1. import java.io.File;
    
  2. import java.io.FileOutputStream;
    
  3.  
    
  4. public class FileLogger implements Logger {
    
  5.   public void printLog(String log) {
    
  6.     try {
    
  7.       File file = new File("log.txt");
    
  8.       FileOutputStream stream = new FileOutputStream(file);
    
  9.       byte[] logInBytes = (new Date() + ": " + log).getBytes();
    
  10.  
    
  11.       stream.write(logInBytes);
    
  12.  
    
  13.       stream.flush();
    
  14.       stream.close();
    
  15.     } catch (Exception e) {
    
  16.       e.printStackTrace();
    
  17.     }
    
  18.   }
    
  19. }
    

Now your code has to cast the objects to the Logger type and then you can uncomment the code.

Example Answer 4.3: Common code.
  1. Logger[] loggerArray = new Logger[2];
    
  2. loggerArray[0] = new ConsoleLogger();
    
  3. loggerArray[1] = new FileLogger();
    
  4.  
    
  5. for (Logger logger : loggerArray) {
    
  6.     logger.printLog("Check point.");
    
  7. }
    
Inheritance Java Programming
Interfaces
Overloading Methods and Constructors