CSCI 241 Labs: PreLab 10
Getting to the Point


 

Introduction

During lab this week you will develop a class to represent 2D points. This document is meant to start you thinking about the design of the Point class.

As you should recall from high school mathematics, two dimensional points have an x component and a y component. That's about it. There is no need to read any further. The class could be defined as:

public class Point
{
public double x;
public double y;
}

In the main we can create Points and access the x and y values without any problems. For example,

public static void main (String [] args)
{
Point p = new Point();
p.x = 5.0;
p.y = 7.0;
System.out.println("(" + p.x + ", " + p.y + ")");
}

This all works, and there is nothing wrong with it, except that it is not very object-oriented. This is exactly the way points are implemented in languages like C and Pascal. Java, which is object-oriented, should be able to do better.

 

Data Encapsulation

Java gives us the ability to hide and protect data within the class. When we declare the x and y values to be private, our class can control access to them. In fact, we have no problem with other objects seeing the x and y values, we just don't want them to be able to change them except through our explicit permission, with a method. You can accomplish this goal by declaring each instance variable to be private and then writing accessor methods to return their values. To allow other objects to update the instance variable values, we write mutator methods. Our class now becomes something like:
public class Point
{
private double x;
private double y;

// get the x value - similar code needed for y
public double getX ()
{
return x;
}

// set the y value - similar code needed for x
public void setY (double newValueForY)
{
y = newValueForY;
}
}
Question: How should you modify the println statement in the main() method above to work with the new class definition?

 

Constructing Points

Now there is another problem with our main program. The two lines:
p.x = 5.0;
p.y = 7.0;
will generate syntax errors, since x and y are no longer public.

We need a way to initialize our points, i.e., to set the x and y values at the time the Point is created. This is exactly why Java includes constructors. A constructor is a method that allows us to initialize an object's data members at the time it is created.

The Point class should have two constructors. The default constructor takes no arguments and sets the point to (0, 0). The second constructor requires two arguments, the initial x value and initial y value. The following lines inside the main program would create points using each constructor.

Point p = new Point(); // creates Point (0,0) using default constructor
Point q = new Point (2.3, -7); // creates Point (2.3,7)

Question: What should the constructors look like in the Point class definition?

 

Other Point Methods

There are a number of other basic operations on points. In Java each of these would be implemented as a public method.
  1. String toString() converts the point to a String for printing. Look at the println statement given in the sample main method above. Every time we want to print a point, we want it to appear as (x, y) where the x and y values are filled in. Our toString() method should format the point for us. The body of this method will be
    return "(" + x + ", " + y + ")";
    The println becomes
    System.out.println(p.toString());

    Aside: While this is an advanced topic, it is worth noting that Java is actually smart enough to invoke the toString() method automatically when printing. The println() could be written as:

    System.out.println(p);
    which would print the same result.

  2. double distanceToOrigin() calculates the distance from the point to (0, 0). As you should recall from high school math, the distance formula is:

  3. double distanceTo(double px, double py) calculates and returns the distance from the point to (px, py). As you should recall from high school math, the distance formula here is:

    Questions:

    1. What will the code look like in the main() method that invokes each of the distance methods?
    2. The last method is an instance method that takes two doubles as parameters. Do you think it could be written to take a second Point as a single parameter, instead?

 

Testing Point Methods

The Point class now has: Seeing that the class compiles is not nearly enough to know that all its methods work correctly. We need to test each method thoroughly. This is one of the real strengths of BlueJ. BlueJ lets us instantiate objects and run their methods without writing any additional code. The disadvantage of testing using BlueJ's object bar is that each test must be run manually. In real world development situations, code is tested and retested and retested. Manual testing would be very inefficient. Tests are typically run through a main program that is responsible for nothing but testing. To retest a program simply requires that you rerun the main.

Testing is not easy, either. To guarantee that a method works, we should test it over several different cases. For example, the distanceTo(double px, double py) should be tested for several arbitrary points. It should also be tested with two points that have the same x value (vertical to each other). Likewise it should be tested for two points that have the same y value (horizontal to each other). Finally, what happens if you ask for the distance from a point to itself?

Questions:

  1. How should we test the constructors?
  2. What tests should be run on the accessors and mutators?
  3. How many different test cases can you think of for the distanceToOrigin() method?

 

The Point of it All

There are many places where having a Point class is useful. For example, two points determine a line. Three nonlinear points give us a triangle. More complex polygons just require more points. In Computer Graphics, each pixel on the screen is treated as a point.

If we just consider triangles, three of our Points determine the triangle. Using methods from our Point class we can determine the perimeter of the triangle. Using our methods and the methods from the ACM graphics library, we can draw the triangle to the screen.

In this week's lab you will get a chance both to create a Point class and exercise it in some interesting applications.