RU beehive logo ITEC Department logo
ITEC 120
2007spring
ibarland,
jpittges

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs

lab15b
inheritance
to avoid repeated code

We will make one new class — Describable — which includes the code repated of Room and Treasure. Then Room and Treasure will extend Describable.

  1. Create class Describable, with fields name and description, along with getters (and setters, if any).
    (You can copy these out of one of the two original classes, of course.)
  2. Should Describable be declared abstract?
    Yes! -- we'll never have an object which is Describable without being something more specific (that is, w/o being a subclass of Describable). (just as we didn't have an Animal which wasn't some subclass of Animal, but we did have Dogs which weren't subclasses of Dog.)
  3. Write a constructor for Describable. (The job of the constructor is to initialize all the fields. That responsibility doesn't disappear just because the class is abstract, or will be inherited from.)
  4. Modify Treasure and Room:
    1. Remove those fields and methods from Treasure and Room.
    2. Have each of these two classes extend Describable.
    3. Modify the constructors so that their first line is a call to Describable's constructor:
      super(  ) .
              
    At this point, your code should compile and behave exactly the same as before (even though there's less of it). Note that if your Treasure had accessed its (private) fields directly instead of using the getters/setters, things have now broken a bit -- the fields are in a different class (Describable), and if they're private then class Treasure can't access them! There are three solutions, from worst to best:
    1. Make the fields in Describable public. Yech.
    2. Make the fields in Describable protected. This is a new privacy setting which means “can be accessed by this class and anybody who extends this class”. This is reasonable, and is often done.
    3. However I still prefer:
    4. Make the fields private, and have a public getter that even other Treasure methods use. (If you want a setter which isn't public, you can make that protected.)
  5. More troubling than the repeated fields and getters, were some static methods dealing for list of Rooms/Treasures: treasuresToString and roomsToString were repeated code, and we also had a method roomsToNamesString (or some-such used by Room's toString) which could apply equally well to Treasures.

    You would certainly think that you just change the parameter-type from LinkedList<Room> to LinkedList<Describable>. Alas: it's not quite so simple, when you have collections of items. You need to give the parameter-type as to LinkedList<? extends Describable>. (Think of this as “a list of Describables, where everything in the list is the same type.”1.)

    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).

  6. Optional: Add the GuiIO class to your project, and have your program use it instead of GuiIO.

    You can even make a abstract class 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 abstract class, both TextIO and GuiIO will extend IO. Then, 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.)

    Since there is no potential for ever having any code or constants inside abstract class IO, really it should instead be declared as an interface. Feel free to do so.

  7. Optional: Making a stand-alone application.
    In order to make your program a stand-alone, clickable application:
    1. Use a GuiIO, as described above.
      (When you double-click on an applicaiton, there is no associated terminal window, so it using a TextIO has no effect. I find this design choice a bit odd.)
    2. Write a main method which starts your whole program running.
    3. From BlueJ (with the main Project window active), choose Project > Save Jar file…. You'll be prompted for which class's main to call upon double-clicking.

1Note 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.      

homeinfoexamslectureslabshws
RecipeLawsliessyntaxjava.lang docsjava.util docs


©2007, Ian Barland, Radford University
Last modified 2007.Aug.27 (Mon)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme