Parameterized Classes (and Interfaces)
in Java |
Prof. David Bernstein |
Computer Science Department |
bernstdh@jmu.edu |
Person
class (that does not
include an ID) and we want to be able to associate
an ID with each Person
object
/** * 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; } }
Object
as a common
ancestor/** * 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; } }
Object
can be "identified"Object
returned by the getEntity()
method will need to be typecast to be used
Object
improperly
which will result in a ClassCastException
being thrown at runtime
public class Identified<T>
/** * 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; } }
Object
is appropriateIdentified<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
Identified i;
, Identified
is the
raw type of Identified<T>
)E
- elementK
- keyN
- numberT
- typeV
- valuepublic static <E> void fillArray(E[] a, E e)
extends
,
followed by the bounding types (separated by an &)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)/** * 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; } }
/** * The requirements of objects that can be ordered. * * @author Prof. David Bernstein, James Madison University * @version 1.0 */ public interface Ordered { /** * Compare this object to the given object. Return -1 if this * is "less than" other, 0 if they are "equal", and 1 if this * is "greater than" other. * * @return -1, 0, or 1 as appropriate */ public abstract int compareTo(Ordered other); }
public interface Comparable<T> { public abstract int compareTo(T other); }
This allows us to avoid the risky typecast that we needed in
the compareTo()
method in the class that realized the
interface.
/** * 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; } }
Statistics
class with
min()
and max()
methods
that had to return an Ordered
Comparable<T>
, but
we want them to return a T
Comparator
InterfaceComparator
:
Person
objects based on
height or weight
Course
objects based on
ID or credit hours
Comparable
and Comparator
interfaces can be used to do more than find the minimum and
maximum, they can be used to sortjava.util.Arrays
Class:
sort()
methods that
take advantage of this observation
Comparator
Course
Class/** * 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)"; } }
Comparator
(cont.)Comparator
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()); } }
Comparator
(cont.)Comparator
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; } }
Comparator
(cont.)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]); } } }
? extends Type
? super Type