Lab #3: Encapsulation & Data Hiding

The goal of this lab is to explore and experience good object oriented design with regards to encapsulation and information hiding. The program you are going to write is simple: it takes commands from the user and produces output. Its functionality is to keep track of the bounding box for points as they are "added". The bounding box for a set of points is the smallest rectangle (aligned with the x/y axis) that contains all the points. The commands are:

  1. add x y adds another point that the bounding box needs to include. No output.
  2. box outputs the current bounding box in the format xmin < x < xmax , ymin < y < ymax.
  3. map x y prints the point (newX,newY), where newX = (x - minX)/width and newY = (y - minY)/height. In these formulas, minX is the minimum x-value in the bounding box, minY is the minimum y-value in the bounding box, and width and height are the bounding box's width and height. If (x,y) is not the current bounding box, it should print "error".
  4. done exits the program

A Sample Run

~/$ java Lab03
add 4 5
add 9 3
add 6 7
box
4.0 < x < 9.0, 3.0 < y < 7.0
map 5 6
0.2 0.75
add 2 6
map 5 6
0.42857142857142855 0.75
box
2.0 < x < 9.0, 3.0 < y < 7.0
done

The Rules

I'm going to try and force you to use good Object Oriented Design practices. So, there are a few rules. First and foremost, in all that you do, all fields are private! Otherwise, here are my rules:

Rule 1: You must define a class Point with at least:

  • the constructor that initializes the points x & y appropriately:
    public Point(double x, double y)
  • the method that reads an x and a y value from the scanner and returns the associated point:
    public static Point read(Scanner sc)
  • the method that returns a String consisting of the x-coordinate, a space, and the y-coordinate:
    public String toString()
Anything else you want in point is OK except that you must declare all data-members (fields) private!

Rule 2: Your program must be able to be run as:

java Lab03
... and it must accept exactly the input syntax described above, and produce exactly the output described above. Also, Step 3 has one more rule!

Rule 3: You must define a class Box with the interface shown below, and no other public methods! Of course, all fields must be private!
public class Box {
  // constructor for Box that consists of a single point
  public Box(Point p) { ... }

  // constructor for the Box containing two initial points
  public Box(Point a, Point b) { ... }

  // growBy(p) expands the bounding box (if needed) to include point p
  public void growBy(Point p) { ... }

  // given point p in the bounding box, returns associated point in the
  // unit square (see notes); returns null if p is not inside the bounding box.
  public Point mapIntoUnitSquare(Point p) { ... }

  // returns string representation like: 2.0 < x < 9.0, 3.0 < y < 7.0
  public String toString() { ... }
}
Note: Just to explain the one-argument constructor, the bounding box around point p should be the "empty box" around that point. For example
Point p = new Point(3,5);
Box B = new Box(p);
String s = B.toString();
System.out.println(s);
... would print out
3.0 < x < 3.0, 5.0 < y < 5.0

Step 1: Get to the Point

You know you're going to want a class Point. Go ahead and write it. Think first of what operations you're likely to need, and then start writing them one-by-one. Make sure to have a

public static void main(String[] args)
you can use to test as you go. Keep adding new code that tests each new function as you add it, but don't get rid of the old tests. When you're done with the program, main() should be a complete test suite you can run to verify that Point works the way it should!

Step 2: Think inside the Box

Now start implementing the Box class. Start with the one-argument constructor and the toString() function. Be sure to include a main() that tests them. Then start adding the other methods, testing as often as you can, and never deleting tests from main(). You may find that you have to go back and add some new methods to Point as you go along. That's OK. Be sure to re-test whenever you do, though!

Step 3: Get with the Program

Finally, write the class Lab03. It should be a breeze now that you've got Box and Point written.
One more rule: Inside the Lab03 class, the only class Point methods you should use are read and toString. You can use any class Box method you want.

~/$ java Lab03
asdf
Error! Unknown command "asdf"!
add 2 2
box
2.0 < x < 2.0, 2.0 < y < 2.0
add 5 1.5
box
2.0 < x < 5.0, 1.5 < y < 2.0
add 2.5 2.5
box
2.0 < x < 5.0, 1.5 < y < 2.5
done
~/$ java Lab03
add 2.8 -1.8
add -3.0 -3.5
box
-3.0 < x < 2.8, -3.5 < y < -1.8
map 0 0
error
map -2 -2
0.1724137931034483 0.8823529411764706
add 2.5 2.5
box
-3.0 < x < 2.8, -3.5 < y < 2.5
map -2 -2
0.1724137931034483 0.25
done

Submit

We are capping the number of times you are allowed to submit. Make sure to test your code offline, and don't just keep trying to blindly submit.

WARNING: you should not have any static methods except for main() and read(Scanner). You will lose many points if you do.

~/bin/submit -c=IC211 -p=lab03 *.java

Review your Submission

Log into the submission site: submit.cs.usna.edu and review the test cases run against your submission.