Comp 170 Week 12
exam Wednesday
Fox-Rabbit
Chapter 10
Run the simulation
version 1: Fox.hunt() and Rabbit.run()
Demo of small window with breeding reduced to zero?
Lab 3: moving more and more stuff into the Animal class
Note that Field.adjacentLocations() [what does this refer to?] returns an iterator. Life would be simpler if it just returned a list, but then we actually have to create the list.
Version 2
We introduce abstract parent class Animal, but at first glance there is only so much we can move to Animal.
Moved to Animal:
- isAlive
- setDead
- getLocation
- getField
- setLocation
These are all "trivial"; they don't do much.
Version 3
We introduce data accessors:
- getAge()/setAge()
- incrementAge()
The following are data accessors, abstract in Animal because they are specific-animal-specific:
- getBreedingAge()
- getMaxAge()
- breedingProbability()
- maxLitter
These allow us to move more routine methods to Animal. Specifically, we
can now move incrementAge to Animal; for example; when it referred to
the constant MAX_AGE it had
to be in Fox or Rabbit, because there's no most-specific-version rule
for references to constants (only for methods). But by converting
MAX_AGE the constant to getMaxAge() the method, we do get the most-specific-method rule to work for us.
But act() still behaves differently for Foxes and Rabbits
Version 4
This is created in the lab.
We break act() up; extract dissimilar pieces of it, and move the rest to Animal.
- breed
- canBreed()
- addBabies()
- act() -- after moving newLocation() out (it remains abstract in Animal; specific to Fox or Rabbit)
Other uses for abstract:
MyShape:
public abstract class MyShape {
...
public abstract void draw();
...
}
Note that Room is not an abstract class, though!
abstract helps you:
- make sure you don't create an instance of that class
- make sure that when you create a subclass, you supply concrete versions of everything you're supposed to.
Exam 2:
Ch 7: good style:
avoid code duplication
use inheritance to help with that
loose coupling between classes is better than "tight" coupling
private fields and clear, general interfaces help here
Cohesion: methods (and classes) should have one fundamental role; ie be responsible for one "thing"
Write for future extendability!
What does this mean? Writing clear
classes and methods with narrow responsibilities helps with reuse.
If you think that one method's actions
might need to evolve (eg Room.respond, Item.print), use polymorphism.
If you will have multiple distinct cases (Item.print, MyShape.draw), use polymorphism.
Refactoring: sometimes you just have to reorganize. Like changing the interface for Room.respond from
Room respond (command c, ArrayList<Item> inv)
to
Room respond (command c, Player p)
Inheritance:
ch 8: basic ideas
ch 9: polymorphism; the most-specific-method rule
ch 10 (and the Zuul project): refinements
Zuul: how do we go from idea to reality?