Parameterized classes in java

Parameterized classes in java

Prof. David Bernstein
James Madison University

  • An Observation:
    • We have had difficulty making our code «type safe» on a few different occasions
    • 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
    • Discuss a more elegant solution
    • A Common Problem:
      • We need to associate an entity with a unique identifier
      • 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
      /** * 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; >>
      • 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)
        • If all of the classes that need to be identified have a common ancestor then we can generalize this solution
        /** * 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; >>
        • An Advantage:
          • Any kind of Object can be «identified»
          • The Object returned by the getEntity() method will need to be typecast to be used
          • The programmer might typecast the Object improperly which will result in a ClassCastException being thrown at runtime
          • An Observation:
            • The compiler normally provides «type safety» (i.e., since Java is strongly typed, the compiler is able to ensure that types conform)
            • It would be nice if we could tell the compiler that the entity being identified must be of a particular type
            • Yes, using a parameterized class (sometimes called a generic class)
            • 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
              • Attributes and methods can use the parameterized type as if it were an actual type
              /** * A parameterized (i.e., type-safe) encapsulation of an Identified entity. * * @author Prof. David Bernstein, James Madison University */ public class Identified  < 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; >>
              • Why Does This Help?
                • We can tell the compiler what kind of Object is appropriate
                • We can bind the parameterized type to a particular class
                Identified person; Identified product; person = new Identified( 10, new Person()); product = new Identified(3415, new Product()); Person fred; fred = person.getEntity(); // This will compile Person barney; barney = product.getEntity(); // This will not compile
                • 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 )
                    • Naming Convention:
                      • Type parameters are normally a single, upper-case letter
                      • E — element
                      • K — key
                      • N — number
                      • T — type
                      • V — value
                      • Type Parameters:
                        • Are listed in an «overlapping» dashed rectangle at the top right of the class, for example:
                        • Use angle brackets in the type specifier
                        • The Need:
                          • A single method in a class that can work with parameterized types
                          • A «generic» method with its own type parameters
                          • Example: public static void fillArray(E[] a, E e)
                          • 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)
                            • List the parameter name followed by extends , followed by the bounding types (separated by an &)
                            • 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 parameterized encapsulation of an Identified entity. * * @author Prof. David Bernstein, James Madison University */ public class Identified  < 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 Situation:
                              • We want to specify the requirements of one or more parameterized classes without specifying the implementation
                              • Create a parameterized interface
                              • Recall that we’ve discussed an example
                              /** * 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

                              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  < 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; >>
                              • 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 , but we want them to return a T
                                • But its complicated and involves techniques that are beyond the scope of this lecture
                                • Use an object that implements the Comparator interface to performing the comparisons
                                • An Added Benefit of Comparator :
                                  • The same object can be compared in multiple different ways
                                  • Comparing Person objects based on height or weight
                                  • Comparing Course objects based on ID or credit hours
                                  • 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
                                    • Contains sort() methods that take advantage of this observation
                                    /** * 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)"; >>
                                    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  < /** * 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()); >>
                                    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  < /** * 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; > >
                                    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) < Comparatorcomparator; 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> >
                                    • Process Details:
                                      • Reifiable/Non-reifiable Types
                                      • Type Erasure
                                      • Covariance: ? extends Type
                                      • Contravariance: ? super Type
                                      • Specialization:
                                        • Specializing a parameterized class
                                        • Specializing the parameters of a parameterized class
                                        • What can be and is inferred?

                                        Источник

                                        How do I pass a class as a parameter in Java?

                                        To create an object of , specify the class name, followed by the object name, and use the keyword : Example Create an object called » » and print the value of x: Try it Yourself » Multiple Objects You can create multiple objects of one class: Example Create two objects of : Try it Yourself » Using Multiple Classes You can also create an object of a class and access it in another class. This is often used for better organization of classes (one class has all the attributes and methods, while the other class holds the method (code to be executed)).

                                        Java Class Methods

                                        Java Class Methods

                                        You learned from the Java Methods chapter that methods are declared within a class, and that they are used to perform certain actions:

                                        Example

                                        Create a method named myMethod() in Main:

                                        myMethod() prints a text (the action), when it is called . To call a method, write the method’s name followed by two parentheses () and a semicolon ;

                                        Example

                                        Inside main , call myMethod() :

                                        public class Main < static void myMethod() < System.out.println("Hello World!"); >public static void main(String[] args) < myMethod(); >> // Outputs "Hello World!" 

                                        Static vs. Non-Static

                                        You will often see Java programs that have either static or public attributes and methods.

                                        In the example above, we created a static method, which means that it can be accessed without creating an object of the class, unlike public , which can only be accessed by objects:

                                        Example

                                        An example to demonstrate the differences between static and public methods :

                                        public class Main < // Static method static void myStaticMethod() < System.out.println("Static methods can be called without creating objects"); >// Public method public void myPublicMethod() < System.out.println("Public methods must be called by creating objects"); >// Main method public static void main(String[] args) < myStaticMethod(); // Call the static method // myPublicMethod(); This would compile an error Main myObj = new Main(); // Create an object of Main myObj.myPublicMethod(); // Call the public method on the object >> 

                                        Note: You will learn more about these keywords (called modifiers) in the Java Modifiers chapter.

                                        Access Methods With an Object

                                        Example

                                        Create a Car object named myCar . Call the fullThrottle() and speed() methods on the myCar object, and run the program:

                                        // Create a Main class public class Main < // Create a fullThrottle() method public void fullThrottle() < System.out.println("The car is going as fast as it can!"); >// Create a speed() method and add a parameter public void speed(int maxSpeed) < System.out.println("Max speed is: " + maxSpeed); >// Inside main, call the methods on the myCar object public static void main(String[] args) < Main myCar = new Main(); // Create a myCar object myCar.fullThrottle(); // Call the fullThrottle() method myCar.speed(200); // Call the speed() method >> // The car is going as fast as it can! // Max speed is: 200 
                                        Example explained

                                        1) We created a custom Main class with the class keyword.

                                        2) We created the fullThrottle() and speed() methods in the Main class.

                                        3) The fullThrottle() method and the speed() method will print out some text, when they are called.

                                        4) The speed() method accepts an int parameter called maxSpeed — we will use this in 8) .

                                        5) In order to use the Main class and its methods, we need to create an object of the Main Class.

                                        6) Then, go to the main() method, which you know by now is a built-in Java method that runs your program (any code inside main is executed).

                                        7) By using the new keyword we created an object with the name myCar .

                                        8) Then, we call the fullThrottle() and speed() methods on the myCar object, and run the program using the name of the object ( myCar ), followed by a dot ( . ), followed by the name of the method ( fullThrottle(); and speed(200); ). Notice that we add an int parameter of 200 inside the speed() method.

                                        Remember that..

                                        The dot ( . ) is used to access the object’s attributes and methods.

                                        To call a method in Java, write the method name followed by a set of parentheses () , followed by a semicolon ( ; ).

                                        A class must have a matching filename ( Main and Main.java ).

                                        Using Multiple Classes

                                        Like we specified in the Classes chapter, it is a good practice to create an object of a class and access it in another class.

                                        Remember that the name of the java file should match the class name. In this example, we have created two files in the same directory:

                                        Main.java
                                        public class Main < public void fullThrottle() < System.out.println("The car is going as fast as it can!"); >public void speed(int maxSpeed) < System.out.println("Max speed is: " + maxSpeed); >> 
                                        Second.java

                                        When both files have been compiled:

                                        Источник

                                        Читайте также:  Input for integer python
Оцените статью