JMU
Parameterized Classes (and Interfaces)
in Java


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Motivation
A Small Motivating Example
One Solution
javaexamples/parameterized/typespecific/Identified.java
/**
 * A type-specific encapsulation of an Identified entity.
 *
 * @author  Prof. David Bernstein, James Madison University
 */
public class Identified
{
    private int       id;
    private Person    entity;
    
    /**
     * Explicit Value Constructor.
     *
     * @param id      The unique identifier for the entity
     * @param entity  The entity
     */
    public Identified(int id, Person entity)
    {
        this.id     = id;
        this.entity = entity;
    }
    
    /**
     * Get the ID of this Identified entity.
     *
     * @return   The ID
     */
    public int getID()
    {
        return id;
    }

    /**
     * Get the entity.
     *
     * @return   The entity
     */
    public Person getEntity()
    {
        return entity;
    }
}
        
Thinking About This Solution
A Generic Solution
javaexamples/parameterized/object/Identified.java
/**
 * A generic but not type-safe encapsulation of an Identified entity.
 *
 * @author  Prof. David Bernstein, James Madison University
 */
public class Identified
{
    private int       id;
    private Object    entity;
    
    /**
     * Explicit Value Constructor.
     *
     * @param id      The unique identifier for the entity
     * @param entity  The entity
     */
    public Identified(int id, Object entity)
    {
        this.id     = id;
        this.entity = entity;
    }
    
    /**
     * Get the ID of this Identified entity.
     *
     * @return   The ID
     */
    public int getID()
    {
        return id;
    }

    /**
     * Get the entity.
     *
     * @return   The entity
     */
    public Object getEntity()
    {
        return entity;
    }
}
        
Thinking About This Generic Solution
Can We Fix It?
Creating Parameterized Classes
A Parameterized Solution
javaexamples/parameterized/Identified.java
/**
 * A parameterized (i.e., type-safe) encapsulation of an Identified entity.
 *
 * @author  Prof. David Bernstein, James Madison University
 */
public class Identified<T>
{
    private int       id;
    private T         entity;
    
    /**
     * Explicit Value Constructor.
     *
     * @param id      The unique identifier for the entity
     * @param entity  The entity
     */
    public Identified(int id, T entity)
    {
        this.id     = id;
        this.entity = entity;
    }
    
    /**
     * Get the ID of this Identified entity.
     *
     * @return   The ID
     */
    public int getID()
    {
        return id;
    }

    /**
     * Get the entity.
     *
     * @return   The entity
     */
    public T getEntity()
    {
        return entity;
    }
}
        
Binding the Parameterized Type
Using the Parameterized Solution
javaexamples/parameterized/Driver.java (Fragment: 0)
        Identified<Person>   person;
        Identified<Product>  product;
        
        
        person  = new Identified<Person>(   10, new Person());
        product = new Identified<Product>(3415, new Product());


        Person fred;
        fred   = person.getEntity();  // This will compile

        Person barney;
        barney = product.getEntity(); // This will not compile
        
Terminological Issues
Style Issues
UML Issues
Another Situation
Bounded Type Parameters
A Bounded Solution
javaexamples/parameterized/bounded/Identified.java
/**
 * A bounded parameterized encapsulation of an Identified entity.
 *
 * @author  Prof. David Bernstein, James Madison University
 */
public class Identified<T extends Person>
{
    private int       id;
    private T         entity;
    
    /**
     * Explicit Value Constructor.
     *
     * @param id      The unique identifier for the entity
     * @param entity  The entity
     */
    public Identified(int id, T entity)
    {
        this.id     = id;
        this.entity = entity;
    }
    
    /**
     * Get the ID of this Identified entity.
     *
     * @return   The ID
     */
    public int getID()
    {
        return id;
    }

    /**
     * Get the entity.
     *
     * @return   The entity
     */
    public T getEntity()
    {
        return entity;
    }
}
        
Interfaces
An Example of a Parameterized Interface
An Example of a Parameterized Interface (cont.)

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
/**
 * A simple encapsulation of a Person.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 2.0 (Using Comparable)
 */
public class Person implements Comparable<Person>
{
    private int    age;    
    private String name;

    /**
     * Constructor.
     *
     * @param name  The name
     * @param age   The age
     */
    public Person(String name, int age)
    {
        this.name = name;
        this.age  = age;
    }

    /**
     * Compare the Person to the given object based on age. Return -1
     * if this is "less than" other, 0 if they are "equal", and 1 if
     * this is "greater than" other. (Required by Comparable)
     *
     * @param other  The Person to compare to
     * @return -1, 0, or 1 as appropriate
     */
    public int compareTo(Person other)
    {
        if       (this.age  < other.age) return -1;
        else if  (this.age == other.age) return  0;
        else                             return  1;
    }

    /**
     * Get the age.
     *
     * @return  The age
     */
    public int getAge()
    {
        return age;
    }

    /**
     * Get the name.
     *
     * @return  The name
     */
    public String getName()
    {
        return name;
    }
}
        
An Example of a Parameterized Interface (cont.)
The Comparator Interface
Sorting
An Example Using Comparator
A Course Class
javaexamples/parameterized/Course.java
/**
 * A simple encapsulation of a course.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class Course
{

    private int     credits;    
    private String  department, number;
    
    /**
     * Explicit Value Constructor.
     *
     * @param depatment   The department identifier (e.g., "CS")
     * @param number      The course nbumber (e.g., "159")
     * @param credits     The number of credits
     */
    public Course(String department, String number, int credits)
    {
        this.department = department;
        this.number     = number;
        this.credits    = credits;
    }
    
    /**
     * Returns the number of credits asscoiated with this Course.
     *
     * @return   The number of credits
     */
    public int getCredits()
    {
        return credits;
    }

    /**
     * Returns the ID of this Course.
     *
     * @return   The ID
     */
    public String getID()
    {
        return department + number;
    }

    /**
     * Return a String representation of this Course.
     *
     * @return   The String representation
     */
    public String toString()
    {
        return getID() + " (" + getCredits() + "cr)";
    }
}
        
An Example Using Comparator (cont.)
One Comparator
javaexamples/parameterized/IDComparator.java
import java.util.Comparator;

/**
 * A Comparator for Course objects that uses the ID.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class IDComparator implements Comparator<Course>
{
    /**
     * Compares two Course objects (using their IDs)
     * (required by Comparator).
     *
     * @param a   Object a
     * @param b   Object b
     * @return   -1, 0, 1 (as per Comparator)
     */
    public int compare(Course a, Course b)
    {
        return a.getID().compareTo(b.getID());
    }
}
        
An Example Using Comparator (cont.)
Another Comparator
javaexamples/parameterized/CreditComparator.java
import java.util.Comparator;

/**
 * A Comparator for Course objects that uses the number of credits.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class CreditComparator implements Comparator<Course>
{
    /**
     * Compares two Course objects (using their credit hours)
     * (required by Comparator).
     *
     * @param a   Object a
     * @param b   Object b
     * @return   -1, 0, 1 (as per Comparator)
     */
    public int compare(Course a, Course b)
    {
        int     an, bn;
        
        an = a.getCredits();
        bn = b.getCredits();
        
        if      (an < bn) return -1;
        else if (an > bn) return  1;
        else              return  0;
    }
}
        
An Example Using Comparator (cont.)
A Simple Application
javaexamples/parameterized/CourseDriver.java
import java.util.*;


/**
 * An application that can be used to demonstrate the power
 * of the Comparator interface.
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class CourseDriver
{
    /**
     * The entry point of the application.
     *
     * @param args  The command-line arguments
     */
    public static void main(String[] args)
    {
        Comparator<Course> comparator;        
        Course[]           prog;
        
        prog = new Course[3];
        prog[0] = new Course("CS", "240", 3);
        prog[1] = new Course("CS", "159", 3);
        prog[2] = new Course("CS", "139", 4);

        comparator = new IDComparator();        
        Arrays.sort(prog, comparator);
        
        System.out.println("\nSorted by ID:");        
        print(prog);
        
        comparator = new CreditComparator();        
        Arrays.sort(prog, comparator);
        
        System.out.println("\nSorted by Credits:");        
        print(prog);
        
    }

    /**
     * Print an array of Course objects.
     *
     * @param courses   The array.
     */
    private static void print(Course[] courses)
    {
        for (int i=0; i<courses.length; i++) 
        {
            System.out.println(courses[i]);
        }
    }
    
}
        
Beyond the Scope of this Lecture
Beyond the Scope of this Lecture (cont.)