Generic Interfaces – Generics

Generic Interfaces

Generic types also include generic interfaces, which are declared analogous to generic classes. The specification of formal type parameters in a generic interface is the same as in a generic class. Example 11.3 declares a generic interface that defines the reference type IMonoLink<E> for objects that store a data value of type E.

Example 11.3 A Generic Interface and Its Implementation

Click here to view code image

interface IMonoLink<E> {
  void         setData(E data);
  E            getData();
  void         setNext(IMonoLink<E> next);
  IMonoLink<E> getNext();
}
class MonoNode<E> implements IMonoLink<E> {
  private E            data;    // Data
  private IMonoLink<E> next;    // Reference to next node                   (1)
  MonoNode(E data, IMonoLink<E> next) {                                  // (2)
    this.data = data;
    this.next = next;
  }
  @Override public void setData(E data) { this.data = data; }
  @Override public E    getData()       { return this.data; }
  @Override public void setNext(IMonoLink<E> next) { this.next = next; } // (3)
  @Override public IMonoLink<E> getNext()          { return this.next; } // (4)
  @Override public String toString() {
    return this.data.toString() + (this.next == null? “” : “, ” + this.next);
  }
}

A generic interface can be implemented by a generic (or a non-generic) class:

Click here to view code image

class MonoNode<E> implements IMonoLink<E> {
  // …
}

Note that the construct <E> is used in two different ways in the class header. The first occurrence of <E> declares E to be a type parameter, and the second occurrence of <E> parameterizes the generic interface with this type parameter. The declare-before-use rule also applies to type parameters. The version of the MonoNode class in Example 11.3 differs from the Node class in Example 11.2 at (1), (2), (3), and (4). These changes were necessary to make the MonoNode<E> class compliant with the IMonoLink<E> interface.

A generic interface can be parameterized in the same way as a generic class. In the code below, the reference strNode has the parameterized type IMonoLink<String>. It is assigned the reference value of a node of inferred type MonoNode<String>. The assignment is legal, since the parameterized type MonoNode<String> is a subtype of the parameterized type IMonoLink<String>:

Click here to view code image

IMonoLink<String> strNode2 = new MonoNode<>(“Bye”, null);
System.out.println(strNode2.getData());                    // Prints: Bye

As with non-generic interfaces, generic interfaces cannot be instantiated either:

Click here to view code image

IMonoLink<String> strNode3 = new IMonoLink<>(“Bye”, null); // Compile-time error!

Example 11.4 shows a non-generic class implementing a generic interface. The generic interface IMonoLink<E> is parameterized by a concrete type, namely, Lymph. The type LymphNode is a subtype of the parameterized type IMonoLink<Lymph>, as it implements the methods of the generic interface IMonoLink<E> in accordance with the concrete type parameter Lymph.

The Java standard library contains many examples of generic interfaces. The two interfaces java.lang.Comparable<E> and java.util.Comparator<E> are discussed in detail in §14.4, p. 761, and §14.5, p. 769, respectively. The Java Collections Framework also includes many examples of generic interfaces, such as Collection<E>, List<E>, Set<E>, and Map<K,V> (Chapter 15, p. 781).

Example 11.4 A Non-Generic Class Implementing a Generic Interface

Click here to view code image

// File: LymphNode.java
class Lymph { /*… */ }
public class LymphNode implements IMonoLink<Lymph> {
  private Lymph            body;
  private IMonoLink<Lymph> location;
  @Override public void  setData(Lymph obj) { body = obj; }
  @Override public Lymph getData()          { return body; }
  @Override public void  setNext(IMonoLink<Lymph> loc) { this.location = loc; }
  @Override public IMonoLink<Lymph> getNext()          { return this.location; }
}

Leave a Reply

Your email address will not be published. Required fields are marked *