- Forward


Parameterized Classes (and Interfaces)
in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Motivation
Back SMYC Forward
  • An Observation:
    • We have had difficulty making our code "type safe" on a few different occasions
  • How We Have Handled These Cases:
    • We have used type casting and/or used overloaded methods (one of which was type safe and the other of which wasn't)
    • We have created multiple classes that were very similar
  • This Lecture:
    • Discuss a more elegant solution
A Small Motivating Example
Back SMYC Forward
  • A Common Problem:
    • We need to associate an entity with a unique identifier
  • An Example:
    • We have a Person class (that does not include an ID) and we want to be able to associate an ID with each Person object
One Solution
Back SMYC Forward
javaexamples/parameterized/typespecific/Identified.java
 
Thinking About This Solution
Back SMYC Forward
  • A Shortcoming:
    • We will have to create a class like this for every class that needs to be identified (and the code will be virtually identical)
  • An Observation:
    • If all of the classes that need to be identified have a common ancestor then we can generalize this solution
  • Another Observation:
    • They do!
      All classes have Object as a common ancestor
      Expand
A Generic Solution
Back SMYC Forward
javaexamples/parameterized/object/Identified.java
 
Thinking About This Generic Solution
Back SMYC Forward
  • An Advantage:
    • Any kind of Object can be "identified"
  • A Shortcoming:
    • The Object returned by the getEntity() method will need to be typecast to be used
  • A Danger:
    • The programmer might typecast the Object improperly which will result in a ClassCastException being thrown at runtime
Can We Fix It?
Back SMYC Forward
  • An Observation:
    • The compiler normally provides "type safety" (i.e., since Java is strongly typed, the compiler is able to ensure that types conform)
  • What Would Be Nice:
    • It would be nice if we could tell the compiler that the entity being identified must be of a particular type
  • Is this Possible in Java?
    • Yes, using a parameterized class (sometimes called a generic class)
Creating Parameterized Classes
Back SMYC Forward
  • Parameterized Types in the Class Definition:
    • Class declarations can be parameterized
    • The parameters of the class are listed in angle brackets
    • Example: public class Identified<T>
  • Parameterized Types in Attributes and Methods:
    • Attributes and methods can use the parameterized type as if it were an actual type
A Parameterized Solution
Back SMYC Forward
javaexamples/parameterized/Identified.java
 
Binding the Parameterized Type
Back SMYC Forward
  • Why Does This Help?
    • We can tell the compiler what kind of Object is appropriate
  • How?
    • We can bind the parameterized type to a particular class
Using the Parameterized Solution
Back SMYC Forward
javaexamples/parameterized/Driver.java (Fragment: 0)
 
Terminological Issues
Back SMYC Forward
  • Type Parameter and Type Argument:
    • The type used in the definition of the class is often called the type parameter
    • The type that is being bound to is often called the type argument
  • Raw Type:
    • Used to describe situations in which the type argument (i.e., the the class to bind to) is omitted (e.g., in Identified i;, Identified is the raw type of Identified<T> )
Style Issues
Back SMYC Forward
  • Naming Convention:
    • Type parameters are normally a single, upper-case letter
  • Common Type Parameters:
    • E - element
    • K - key
    • N - number
    • T - type
    • V - value
UML Issues
Back SMYC Forward
  • Type Parameters:
    • Are listed in an "overlapping" dashed rectangle at the top right of the class, for example:
  • Type Arguments:
    • Use angle brackets in the type specifier
Another Situation
Back SMYC Forward
  • The Need:
    • A single method in a class that can work with parameterized types
  • The Solution:
    • A "generic" method with its own type parameters
    • Example: public static <E> void fillArray(E[] a, E e)
Bounded Type Parameters
Back SMYC Forward
  • The Situation:
    • When constructing the parameterized class, you want to restrict the types that can be used as type arguments (i.e., the classes that can be bound to)
  • The Solution:
    • List the parameter name followed by extends, followed by the bounding types (separated by an &)
  • A Notes:
    • The term extends was probably a bad choice since any class that either extends the bounding type or implements the bounding type can be used (which is why there can be more than one)
    • Only one class can be a bounding type and it must appear first in the list; the list can contain multiple interfaces
A Bounded Solution
Back SMYC Forward
javaexamples/parameterized/bounded/Identified.java
 
Interfaces
Back SMYC Forward
  • The Situation:
    • We want to specify the requirements of one or more parameterized classes without specifying the implementation
  • The Solution:
    • Create a parameterized interface
  • An Example Revisited:
    • Recall that we've discussed an example
An Example of a Parameterized Interface
Back SMYC Forward
  • An Example Revisited:
    • javaexamples/oopbasics/interfaces/Ordered.java
       
  • A Parameterized Version (in Java):
    • public interface Comparable<T> { public abstract int compareTo(T other); }
An Example of a Parameterized Interface (cont.)
Back SMYC Forward

This allows us to avoid the risky typecast that we needed in the compareTo() method in the class that realized the interface.

javaexamples/parameterized/comparable/Person.java
 
An Example of a Parameterized Interface (cont.)
Back SMYC Forward
  • A Continuing Shortcoming in this Example:
    • Recall that we had a Statistics class with min() and max() methods that had to return an Ordered
    • Now they can return a Comparable<T>, but we want them to return a T
  • We Can Fix This Using Parameterized Types:
    • But its complicated and involves techniques that are beyond the scope of this lecture
  • A Different Approach:
    • Use an object that implements the Comparator java.util.Comparator interface to performing the comparisons
The Comparator Interface
Back SMYC Forward
  • An Added Benefit of Comparator:
    • The same object can be compared in multiple different ways
  • Some Examples:
    • Comparing Person objects based on height or weight
    • Comparing Course objects based on ID or credit hours
Sorting
Back SMYC Forward
  • An Observation:
    • The Comparable and Comparator interfaces can be used to do more than find the minimum and maximum, they can be used to sort
  • The java.util.Arrays Class:
    • Contains sort() methods that take advantage of this observation
An Example Using Comparator
Back SMYC Forward
A Course Class
javaexamples/parameterized/Course.java
 
An Example Using Comparator (cont.)
Back SMYC Forward
One Comparator
javaexamples/parameterized/IDComparator.java
 
An Example Using Comparator (cont.)
Back SMYC Forward
Another Comparator
javaexamples/parameterized/CreditComparator.java
 
An Example Using Comparator (cont.)
Back SMYC Forward
A Simple Application
javaexamples/parameterized/CourseDriver.java
 
Beyond the Scope of this Lecture
Back SMYC Forward
  • Process Details:
    • Reifiable/Non-reifiable Types
    • Type Erasure
  • Wildcards:
    • Covariance: ? extends Type
    • Contravariance: ? super Type
Beyond the Scope of this Lecture (cont.)
Back SMYC Forward
  • Specialization:
    • Specializing a parameterized class
    • Specializing the parameters of a parameterized class
  • Type Inference:
    • What can be and is inferred?
There's Always More to Learn
Back -