![]() |
![]() |
|
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
We will make one new class — Describable — which includes the code repeated of Room and Treasure. Then Room and Treasure will extend Describable.
super( … ) . |
Challenge: More troubling than the repeated fields and getters, were some static methods dealing for list of Rooms/Treasures: treasureListToString and roomListToString were repeated code.
You would certainly think that you just change the parameter-type from LinkedList<Room> to LinkedList<Describable>, and then your function can be passed either a List<Room> or a List<Treasure>. Alas: it's not quite so simple1, when you have collections of items. You need to give the signature as
public <T extends Describable> String DescribablesToString( java.util.List<T> items ) |
Note that this is a new syntax — up til now, the angle-brackets were always part of some type's name. Here, the angle-brackets before the signature are extra type-information, to appease Java's type-checking. It's worth pondering, every now and then, how much Java's type system helps us by catching errors early, vs. gets makes us go through contortions to do what we want. Tomorrow's lecture on the command pattern raises similar issues.
Once you have this method describablesToString, you can collapse TextIO's two methods selectRoom and selectTreasure into one. Run your program, to make sure everything works the same as before (with even less code).
Optional; this step requires that you have already added the GuiIO class to your project, as in hw-ec05.
Make a interface IO. It declares methods display, prompt, etc. each of them as an abstract method (a declaration without a body):
public abstract String prompt( String msg ) |
Once you have the interface
both TextIO and GuiIO will implement IO.
Finally, in Explorer
instead of a local variable whose declared type is TextIO,
that variable's declared type should be IO.
This variable will be
initialized with (either) a new GuiIO() or a new TextIO().
(This time, the refactoring it doesn't eliminate any repeated code,
but it helps sets us up for any future methods which want to be given an IO
but don't care which type they get.)
Why not? If a Treasure is-a Describable, then List<Treasure> is-a List<Describable>, right? Wrong! There is something you can do with a List<Describable>, that you can't do with a List<Treasure>: add a Room to it.
We say that lists are contravariant, if “A extends B” doesn't imply “list-of-A extends list-of-B”.
↩2Note that “LinkedList<Describable>” refers to a list which may contain both Rooms and Treasures at the same time. But that's not what we're passing in, which is why the extra “question-mark” notation is needed. ↩
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
©2007, Ian Barland, Radford University Last modified 2007.Dec.05 (Wed) |
Please mail any suggestions (incl. typos, broken links) to ibarland ![]() |
![]() |