A 'generic type' can also be defined for an 'interface class', for example: interface Pair { T1 getFirst(); T2 getSecond(); } Now the types can either be fixed when writing the class implementing the interface… class StudentPair implements Pair { private Student s1; private Student s2; public StudentPair(Student s1, Student s2) { this.s1 = s1; this.s2 = s2; } @Override public Student getFirst() { return s1; } @Override public Student getSecond() { return s2; } } ...or also write the implementing class 'generically typed', in which case the type is given only when an object is created from the class: class Tuple implements Pair { private T1 first; private T2 second; public Tuple(T1 first, T2 second) { this.first = first; this.second = second; } @Override public T1 getFirst() { return first; } @Override public T2 getSecond() { return second; } } Example of using the class: public static void main(String[] args) { Tuple numbers = new Tuple<>(10, 0.25); System.out.println(numbers.getFirst()); System.out.println(numbers.getSecond()); } The program prints: 10 0.25