Purpose:
To practice the design of methods for complex classes, abstracting fields and methods of classes, and designing World programs.
Part 1: Methods for Complex Class Hierarchies
Below is a class diagram for a mutually-recursive class hierarchy that represents the management levels in a large company.
+-----------+ | Employee |<-------------------------+ +-----+-----+ | / \ | +---+ | | | +---------------+-----------------+ | | | | +-------+-------+ +------+--------+ | | Worker | | Manager | | +---------------+ +---------------+ | | String name | | String name | | | int tasks | | String unit | | +---------------+ +--------| ILoE subs | | | +---------------+ | V | +--------------+ | | ILoE |<--------------------)--+ +------+-------+ | | / \ | | +---+ | | | | | +--------------+---------------+ | | | | | | +-------+------+ +--------+---------+ | | | MtLoE | | ConsLoE | | | +--------------+ +------------------+ | | +--------------+ | Employee first |---+ | | ILoE rest |------+ +------------------+
Exercise 1:
Define the classes that implement this class diagram. Make some examples... be sure you have one that represents a company with at least 2 manager levels.
Exercise 2:
Design a method countEmployees (for the entire hierarchy) that determines the number of Employees that this Employee has as coworkers and/or subordinates (including themselves).
Hint: think about it case-by-case.Exercise 3:
Design a method allCoworkers that computes a list of all employees this Employee has as coworkers.
Exercise 4:
Design a method hasSub that that determines whether or not this Employee has a subordinate with the given name. Hint: this may require more than just one method... since we don't want a worker to count themselves as a subordinate.
Part 2: Abstracting Classes and Methods
If you look over this part and can easily and quickly sketch in your head where the different methods should go and how you would write them, you may want to skip to Part 3 and come back to this if you have time. But many of you seem to need more work on creating a Union structure and deciding when to abstract methods into higher classes.
We've gone over several different abstraction scenarios in class. Here's one more for you to practice all the different types of object-oriented abstractions (besides the obvious method/function abstraction we saw last semester).
Exercise 5:
Design 3 classes to represent bank accounts: Savings, Checking, and CertDep. Each one has an owner, balance, and account id. A Savings account also has an interest rate, Checking has a minimum balance, and CertDep has an interest rate, and a boolean that signifies whether or not the account is mature (can be withdrawn from).
Exercise 6:
If you didn't already do it (hint, hopefully you did), create an abstract class called Account that is the superclass of each of your account classes. Determine which fields can be moved to the superclass, and which must remain in the subclasses.
Exercise 7:
Design the following methods for your classes. For each one, determine at which level you can implement it (super/subclass) by seeing in which category it falls:
Here's what you should implement:
- All implementations are the same -- the method can be completely defined in the superclass.
- All implementations are different -- method is abstract in the superclass and implemented/overridden in each subclass.
- Most implementations the same, but some are different -- the superclass implements default behavior, which is overridden by subclasses when needed.
- Design the method canWithdraw that determines whether or not the owner can withdraw the given amount from this Account... i.e., the balance is greater than the given amount. Note: one cannot withdraw from a CertDep account until it is mature.
- Design the method getOwner that returns the name of this Account's owner.
- Design the method makeDeposit that returns a new Account after adding the given amount.
- Design the method interest that calculates the interest this Account has earned. Note, there are several ways to do this, so feel free to implement it in a few different ways.
Part 3: Worlds and Zombies
I've been showing you some games in lecture, now you finally get to make one! [you've come so far, so quickly :-)]
Your task is to develop a simple game where a player moves around on screen and tries to get away from Zombies. On each tick the zombies move one step closer to the player. In the real game the zombies die if they run into each other, and the player dies if a live zombie reaches him (or her), but we'll keep it simple for now.Setup:
Save the JavaWorld.jar somewhere and add it to the build-path for your project (if it's not done already). Grab the images below (or substitute better ones if you can find them) and save them in your project directory (the one that contains src and bin).
Right Left Hero Data Design:
Design classes to represent the following pieces of information:
Make some examples of worlds with which we can start. Make sure the hero isn't too close to any zombies and there are at least three of them for him to run away from.
- A position, which uses doubles (instead of ints). A position will represent both the zombies and our hero.
- A list-of-positions (for the list of zombies). Eventually we will add methods to make the magic happen.
- The world (a hero position, and a list of zombies, plus any other information you think is relevant).
Method Design:
Before we get to the World methods, we need to design methods that make the whole thing work. Feel free to skim lecture notes for a few of the details.
- Design a method distance for your position class that calculates the distance between this and a given position.
Design a method moveToward for your position class that returns a new position that is moved toward the given position.
This might be a little tricky, but you'll want something like the following:new_x = this.x + (that.x - this.x)/this.distance(that)*SPEED; new_y = this.y + (that.y - this.y)/this.distance(that)*SPEED;Mess around with the formula until you get something you expect. Hint: make up some easy numbers to test.- Design a method moveAllToward for your list-of-position classes that returns a new list with all the positions moved toward a given position.
- Design a method drawZombies for your list-of-position classes that places a zombie at each position in the list. If you feel like it, try to determine which way the zombie should be facing. Use the FromFile image class to read your zombie image(s), which can be placed as a constant somewhere in your List classes.
Complete the World:
Finish the parts of the world by designing the interaction/drawing methods.
- Design a method placeHero that places the hero into a given scene.
- Design the public method onTick that creates a new World after moving the zombies.
- Design the public method onMouse that moves the hero to the given x/y. The signature should be as follows, though you should substitute your world class for "World":
public World onMouse(int x, int y, String event)Don't worry about the conversion from int to double, it will happen automatically. See the Documentation for more information about mouse events.- Design the public method onDraw that places the hero and the zombies into an EmptyScene. Use the methods you wrote earlier... remember?
Run the World:
Run the program! See the lecture notes for getting the world example to run within the tester. If you have trouble ask a tutor or instructor.
Save your work... you might need to extend this game for the next HW.
If you finish try making it better! See the world class documentation for explanations of methods you can override and other features you can add. Enjoy.