Comp 170 Week 11

Point of Zuul: how do we get from the idea to the reality? For general programming, this is hard. But it is easier (not easy, but easier) to go from an idea for a Zuul room puzzle to an implementation of it.

Zuul 4.0

    ValveRoom
    DustyRoom
    ZooRoom
    DarkRoom
   
DarkRoom
       Flashlight; Light generally
       Note that an Item can now have added attributes besides its name! Yet TAKE, DROP still work without changes.

    How class Light works, with (cast): occasional need for downcasting.

Casting
What if we wanted to do something CD-specific in the printing? Suppose we had a special method, printCD().
We could use
    if (item instanceof CD)
       item.print();
to print only the CDs. But if we try replacing print() with printCD(), we get an error: the variable item has static type Item, even though we know at this point that the object it contains has dynamic type CD. We need a variable with static type CD! We can't do "CD cd = item" either, because while that isn't a mismatch, it goes in the wrong direction.

What we need is a cast:
    if (item instanceof CD) {
       CD cd = (CD) item;   // the cast
       cd.printCD();
    }

Now what if we have our inventory, which is an ArrayList of Item, and we want the flashlight, as a Light? We can find it easily enough with Item.getByName(), but we then need a cast to convert it from Item to Light. Note how those "extra fields" (that a Light has that an Item doesn't) just get carried along for the ride.

class Light is cleaned up
Game.findByName is moved to Item.findByName

Linked-valveroom example

Player class version; Player holds:
Main change: the second parameter to Room.respond() is now Player p.
This isn't about support for multiple players; it's about the recognition that all the information for one player should be kept in a single place.

As part of basic hinting to the player, it is very important that all valid verbs be recognized as such in all rooms, even if they don't work there. For example, in the theater, if you type
    GIVE COOKIE
the response is "You can't do that here" (emphasis added),
not "I don't know what you mean"


Wednesday:

Shapes lab, with MyShape base class

MyShape fields: xPosition, yPosition, color, isVisible. These are the attributes of any shape.

What methods moved to the base class?
A method belongs in a specific-shape class only if it needs to be there; that is, if a general version can't be made. There's no point to having subclasses if this isn't true for any method, but often there's only one or two critical ones. The critical ones here are draw() and changeSize().

Consider how the Picture class works: we create a bunch of specific shapes, add them to shapelist, and then draw each shape on shapelist. We could draw the shapes as we went along, but that wouldn't change the advantages of inheritance. One advantage of shapelist is that it allows us to redraw the whole picture, either to move it, or to "draw" it to a printer.

What if we tried to avoid MyShape, and simply tried to use the fact that Circle, Rect, and Triangle are all subclasses of Object? The problem here is that Object is too general: it has no draw() method. It is critical that the base class we use is general enough to include Circle, Rect, and Triangle, but specific enough that it has a draw() method (and all the other methods above).

Other possible MyShape subclasses:
    Text
    Polygon
    Group
Note that if we were to define one of these, and include it in our Picture, the code that draws everything on shapelist would still work! No changes would be necessary to accommodate the new types.

Note also that we will never create a MyShape object; that is, an object whose dynamic type is MyShape, eg
    MyShape s = new MyShape(...)
Such a thing could never be drawn, it is too general!

However, in Zuul 3.0, we do have a whole bunch of "general" rooms, of type Room: the Room objects provide "filler" and do not have special behavior.

MyShape is the classic objects-know-how-to-draw-themselves example.

protected v private




Square and Rect
In one sense, it is clear that a Square "is a" Rect, or "is a kind of". However, there's an annoying issue here: you can take a square s, and apply s.changeSize(4,7). It's now not square!

This is a fundamental problem, having to do with the idea that a Square is not a Rect with extra fields. It's a Rect with a constraint on the existing fields. We need to be sure all mutators respect that constraint, or are blocked (eg by "shadowing": redefining within Square)



Fox-Rabbit

Chapter 10

Run the simulation
Look briefly at the v1 code, and in particular at the Fox and Rabbit classes.

can we figure out the rules? Breeding is probabilistic. Locations of offspring is probabilistic.


version 2: the Animal superclass (just started Week 11)



Object
    toString()
Go back to the Club example, in Membership.java
Add toString instead of print() to DoME?

Notice that this is yet another advantage of inheritance + polymorphism: you can build in these predefined "hooks" into standard libraries (like System.out.println())