Discussion 6: 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
- Identify three scenarios where subtype substitution is permitted.
- Explain the benefits of leveraging polymorphism in object-oriented code.
- Implement a generic class or method with one or more generic type parameters. Use generic classes in client code.
Reminder: Discussion Guidelines
The work that you complete in discussion serves as a formative assessment tool; it offers the opportunity to assess your understanding of the material and for our course staff to get a “pulse” on how things are going, so we can make adjustments in future classes. Your grade in discussion is based on your attendance, active participation, and completion of that day’s activity. More information about the grading and expectations can be found in the syllabus.
Since discussion activities are not graded for correctness, we do not restrict what resources you may use to complete them, which include notes, books, unrestricted conversations with other students, internet searches, and the use of large language models or other generative AI. We advise you to be pragmatic about your use of these resources and think critically about whether they are enhancing your learning. Discussion activities are intended to serve as “strength training” for programming tasks we will expect on assignments and exams (and that you will encounter in future courses and careers), and their main benefit comes from thinking critically to “puzzle” them out.
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:
|
|
|
|
DoublePair, which behaves exactly like an IntPair, but for doubles.
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.
What shortcoming does this suggest in Alice’s approach to modeling pairs?
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.
Write a generic Pair<T> 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.
(We’d like you to submit your code written out with your responses. Writing this (relatively short) code by hand will help build muscle memory for upcoming exams. It can be challenging to get used to, since you can’t rely on IntelliJ’s linter to point out syntax errors.)
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 on two type parameters T1 and T2 modeling the types of its entries (that is, the class declaration should have the form class AsymPair<T1,T2>). 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 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.
Player with subclasses Quarterback and TightEnd.
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This last one is a bit tricky! Think carefully about whether the assignment on the last line should be allowed.
|
|
|
|
Submission
At the end of class, your group’s primary author should create a PDF with your written answers and upload this to the “Discussion 6” Gradescope assignment, tagging all other members of the group onto the submission.