OCA Java SE 8 Class Design - Java Interface 2








Classes Interfaces

A class can implement an interface, but a class cannot extend an interface.

An interface can extend another interface, but an interface cannot implement another interface.

The following examples illustrate these principles:

public interface Formattable {} 

public class PaperA extends Formattable {}  // DOES NOT COMPILE 

public class PaperB {} 

public interface Printable extends PaperB {} // DOES NOT COMPILE 

The first line shows a class trying to extend an interface that doesn't compile.

The fourth line shows an interface trying to extend a class, which also doesn't compile.





Abstract Methods and Multiple Inheritance

The following code shows what will happen if you define a class that inherits from two interfaces that contain the same abstract method:

public interface Printable { 
  public void format(); 
} 

public interface Formattable { 
  public void format(); 
  public void cutPaste(); 
} 

In this scenario, the signatures for the two interface methods format() are compatible, so you can define a class that fulfills both interfaces simultaneously:

public class Shape implements Printable, Formattable { 
  public void cutPaste() { 
    System.out.println("cut paste"); 
  } 
  public void format() { 
    System.out.println("format"); 
  } 
} 

If the method name is the same but the input parameters are different, there is no conflict because this is considered a method overload.

public interface Printable { 
  public int format(int quantity); 
} 

public interface Formattable { 
  public void format(); 
} 

public class Shape implements Printable, Formattable { 
  public int format(int quantity) { 
    System.out.println("format: "+quantity); 
    return quantity; 
  } 
  public void format() { 
    System.out.println("format"); 
  } 
} 

Unfortunately, if the method name and input parameters are the same but the return types are different between the two methods, the class or interface attempting to inherit both interfaces will not compile.

It is not possible in Java to define two methods in a class with the same name and input parameters but different return types.

Given the following two interface definitions for Printable and Formattable, the following code will not compile:

public interface Printable { 
  public int format(); 
} 

public interface Formattable { 
  public void format(); 
} 

public class Shape implements Printable, Formattable { 
  public int format() {  // DOES NOT COMPILE 
    System.out.println("format: 10"); 
    return 10; 
  } 
  public void format() {  // DOES NOT COMPILE 
    System.out.println("format"); 
  } 
} 

The compiler would throw an exception if you define an interface or abstract class that inherits from two conflicting interfaces, as shown here:

public interface Printable { 
  public int format(); 
} 

public interface Formattable { 
  public void format(); 
} 

public interface Supervore extends Printable, Formattable {} // DOES NOT COMPILE 

public abstract class AbstractShape implements Printable, Formattable {} 
// DOES NOT COMPILE 

Even without implementation details, the compiler detects the problem with the abstract definition and prevents compilation.





Interface Variables

interface variables are assumed to be public, static and final.

Marking a variable as private or protected will trigger a compiler error.

The value of an interface variable must be set when it is declared since it is marked as final.

interface variables are constant variables defined on the interface level.

Because they are assumed to be static, they are accessible without an instance of the interface.

The following two interface definitions are equivalent, because the compiler will automatically convert them both to the second example:

public interface Printable { 
  int MAXIMUM_DEPTH = 100; 
  final static boolean SIZE = true; 
  public static final String TYPE = "A4"; 
} 

public interface Printable { 
  public static final int MAXIMUM_DEPTH = 100; 
  public static final boolean SIZE = true; 
  public static final String TYPE = "A4"; 
} 

The compile will automatically insert public static final to any constant interface variables.

Based on these rules, the following entries will not compile:

public interface Printable { 
  private int MAXIMUM_DEPTH = 100;  // DOES NOT COMPILE 
  protected abstract boolean SIZE = false;  // DOES NOT COMPILE 
  public static String TYPE;  // DOES NOT COMPILE 
} 

MAXIMUM_DEPTH doesn't compile because the private modifier is used, and all interface variables are assumed to be public.

SIZE doesn't compile for two reasons. It is marked as protected, which conflicts with the assumed modifier public, and it is marked as abstract, which conflicts with the assumed modifier final.

TYPE doesn't compile because it is missing a value. The modifiers are correct, but you must provide a value to a static final member of the class when it is defined.