Discussion 7: Generic Types

In today’s discussion, you’ll practice using and reasoning about generic types in Java. In particular, you’ll explore their connections to data structures and the subtyping rules that we learned about in recent lectures. You’ll see what problem(s) generics conceptually solve, and use them to implement some simple generic collection types.

Learning Outcomes

  1. Identify three scenarios where subtype substitution is permitted.
  2. Explain the benefits of leveraging polymorphism in object-oriented code.
  3. Implement a generic class or method with one or more generic type parameters. Use generic classes in client code.
Exercise 1: Other Types of Pairs
Alice is writing a program to construct and interpret scatterplots on a 2D graph. She needs a way to model the (integer) coordinates of a point on the scatterplot, so she decides to do this with a type of (mutable) collection called an IntPair. This type has a constructor that accepts two int arguments (the pair's first and second entries), as well as accessor and mutator methods for each entry. Some example code using Alice's IntPair type is shown below:
As she continues implementing her program, Alice realizes that she will need to represent the coordinates of points in between integer markings. She creates DoublePair, which behaves exactly like an IntPair, but for doubles.
(a)
Alice's physicist friend Bob writes a lot of code performing calculations on his own ComplexNumber type. He'd like to use Alice's pair classes to model complex coordinates within his simulations. Explain why he won't be able to do this.
(b)
What shortcoming does this suggest in Alice's approach to modeling pairs?
(c)
Rather than writing his own ComplexPair class, Bob decides to write a more general Pair class that can store anything in its two entries; its constructor accepts two Objects:
Bob reasons that he can pass in two ComplexNumbers as the constructor arguments (after all, Object is a supertype of ComplexNumber), so he'll be able to use Pairs in his simulation. Moreover, Alice can take advantage of auto-boxing to use Bob's Pair class to model pairs of Integers and Doubles.

Identify two issues with Bob's approach.
Exercise 2: Generic Pairs
We can use generic type parameters to solve the problems that you identified in the previous exercise.
(a)
Write a generic Pair class that models a pair whose entries both have type T. Your definition should provide the first(), second(), setFirst(), and setSecond() methods as described above. Make a note of all the different ways that your code utilized the generic type T parameter.

Pair.java

Pair.java

(b)
Sometimes, we may want the two entries of a pair to have different types. For example, when plotting in polar coordinates, we may want the first entry to have type Double to represent the radius, while the second entry has a custom type Angle to represent the azimuth. Write an AsymPair class generic in two type parameters, T1 and T2, modeling the types of its entries (that is, the class declaration should have the form class AsymPair). Your definition should provide the first(), second(), setFirst(), and setSecond() methods as described above. Make sure you are careful about where you use each generic type.

AsymPair.java

AsymPair.java

(c)
The AsymPair class that you just wrote is a more general type than the Pair class. Use an inheritance relationship with the AsymPair class to redefine the Pair class (while still enforcing that its coordinates both have type T). You should be able to accomplish this with minimal code.

Pair.java

Pair.java

Exercise 3: Generics and Subtypes
For the rest of the discussion, you'll spend some time thinking about how generic types interact with the subtype substitution rules that we discussed in previous weeks. Suppose we define a class Player with subclasses Quarterback and TightEnd.
All of these classes define a constructor with two String arguments, the name and team of the player. Determine whether each of the following code snippets will compile, briefly explaining each of your answers.
(a)
(b)
(c)
(d)
(e)
This last one is a bit tricky! Think carefully about whether the assignment on the last line should be allowed.