CSIT 115 Class 7

Project due tonight—questions?

Making our own objects—need to write a Java class for each kind of new object.

First example: Point objects, Point.java

The big mystery—how do we handle internal state ourselves?

Answer: using “fields” defined in the class for the object.

First way for our own Point, pg. 506

public class Point {

   int x;

   int y;

}

 

This is saying that a Point holds an int called x and an int called y.

<picture of a Point object with x and y inside it, like pic on pg. 504>

This is actually overly simple, but does work.  It allows Points that can hold x and y values inside them.  However, it can’t construct points from coordinates as we expect from the JDK Point class.

Look at PointMain, pg. 507—using Points like this:

Point p1 = new Point();  // create a new point, with p1.x and p1.y state

Now the object exists, with x = y = 0.  We can print these out by using p1.x and p1.y:

System.out.println(“p1 is (“ + x +”,” + y + “)”);

p1.x = 7;   // set x in p1 to 7

<picture of point with (7, 0) inside it>

p1.y = 2;

<picture of point with (7, 2) inside it>

Similarly with another point p2.

Translate p1 by (11, 6):

p1.x += 11;

p1.y += 6;

<picture of point p1 with (18,8) inside it>

We can set up an array of these Points:

Point[] pair = new Point[2];

pair[0] = p1;

pair[1] = p2;

<picture of array of 2 Points, with (11,6) in first and (5,10) in the second element>

Now there are still only two Point objects, but with two names each: p1 and pair[0] for first, p2 and pair[1] for second.

OK, so now we have simple Point objects, but they have no “behavior”, i.e., no methods.

Let’s get them to support the translate method:

We want p1.translate(1,1) to change p1 from (18,8) to (19, 9).

We need a “translate” method for Point..  It should take two int params, the x and y coordinates of the shift, and doesn’t return anything, so basically

  … void translate(int dx, int dy)

Cole on pg. 510 shows the format:  Note the lack of the keyword static here. That’s crucial.  We rarely use “static” in an object class—to start with, just avoid it completely in an object class.  That means no main method in an object class. That’s OK, we can have another class with the main—that’s our plan.

Setup for an object method

public class Point {

  int x;

  int y;

 

  public void translate(int dx, int dy) {

      ß-need code here

  }

}

 

Now the code we need is ordinary Java code, but in an object class setting.  Inside the object, the method parameters and the object fields are easy to access, and the outside world is harder to access.  We try to do everything in terms of the parameters and fields.

To translate x by dx:   x += dx;

To translate y by dy: y += dy;

public class Point {

  int x;                  ßfields x and y

  int y;

 

  public void translate(int dx, int dy) {   ßparameters dx and dy

    x += dx;   ß code using variables that are fields and/or parameters

    y += dy;

  }

}

Note that it’s good to avoid using x and y as parameter names, to avoid ambiguity.

Now think about 2 Points p1 and p2, where p1 = (1,2) and p2 = (10,20) to start.

p1.translate(1,1);   // translate code is using old x = 1, y = 2, changing to (2,3)

p2.translate(1,1);   // translate code is seeing x=10 to start, changing to 11, … end up with (11,21)

So you see that the object method code is working on its own object’s field values, its own internal state. This is called the “implicit parameter”.  It’s sort-of like translate had another parameter forp1 or p2: translateEffective(p1, 1,1)

Analogy from real life: when we drive a car, our universe of control of the car is all inside the car. We can’t honk another car’s horn. The horn of interest is the one inside our car. When we write methods for objects, we are using the variables representing a particular object’s state. It’s like we are inside one particular object.

Another method: distanceFromOrigin, pg. 514.

Demo on Running this program:

Download Point.java and PointMain.java programs from Point_2 of chapter 8 code, compile and run.

Java finds main in PointMain and executes it. It refers to code in Point.java to do Point methods.

Add System.out.println(“ p1 is “ + p);

And see from this line:

 p1 is Point@1bd9d76

How can we get it to work like JDK Points, which print out usefully, as shown on pg. 505.

Answer: we need to implement the toString method.

Unlike translate and distanceFromOrigin, toString’s name has built-in significance in Java. It means the String representation of the object’s state.  We saw the Scanner’s toString representation earlier.

Add toString to demo’s PointMain.  Change it to [1,2] to see it’s under our control.

Adding a Constructor.  We want to say Point p = new Point(2,3);  but that requires us to write a constructor.

public class Point {

    

public Point(int x0, int y0) {    ßname of class, then (parameters) ßspecial syntax

  x = x0;

  y = y0;

}

}

Add to demo program, or download next version from the website.

Try to compile—fails, because default constructor no longer there.

Add parameter-less constructor—works.

Or convert constructor calls.

Now we have a workable object: nice constructor, a few methods.  We could easily add getX(), etc.

But it’s not encapsulated. 

Idea of encapsulation.

One example in real world: Locking your car.

How can that relate to programming?

Data can be damaged if it’s lying around in the open, or misused by mistake. When this happens, it’s very hard to track down.

Better to seal it up in larger units, then allow access at the right time, or the right way.

 

We looked at Point4_encapsulated: see “private” keywords. No longer can use p1.x to get to x value inside p1. Instead, use p1.getX().

 

We looked at Point5_fancy: toString() implemented.