Experiments in Java


Experiments for Session J3: Building Your Own Classes

Name: ________________
ID:_______________

Experiment J3.1: Program state

Consider the following fragment of Java code

    int x = 0;
    int y = 0;
    int z = 0;
    ...
    // potential changes to x, y, and z
    ...
    // position 1 (before the following steps)
    x = 2 * y;
    y = 5;
    z = x + y;
    // position 2 (after the first set of steps)
    x = 2 * y;
    y = 5;
    z = x + y;
    // position 3 (after both sets of steps)

What do you know about the values of x, y, and z at positions 1, 2, and 3?


 
 
 
 
 
 

Experiment J3.2: Fields

Required code files:

Step 1. Make copies of the required code files. Modify PointPrinter.java so that it includes a numprinted field which it prints and updates every time it prints a point. Modify PointFun.java so that it creates and uses a PointPrinter object for output. Compile the various files, execute PointFun, and record the results. Are they what you expected? Why or why not?


 
 
 

Step 2. Rename numprinted to printed everywhere that it appears in PointPrinter.java and recompile. Execute PointFun and record the results. Are they what you expected? Why or why not?


 
 
 

After recording your answer, you may wish to look at the notes on this step.

Experiment J3.3: Fields, revisited

Step 1. Create a new class, MyPoint, that contains two integer fields, xcoordinate and ycoordinate. Note that all you will need for this class (at least at this point) are the class declaration and the field declarations. (Do not initialize the fields, just declare them.) Compile your class and correct any errors reported by the compiler. Enter the code for your class here.


 
 
 
 
 
 
 
 
 
 
 
 
 
 

Step 2. Create a print(SimpleOutput out) method for your MyPoint class. This method should print out the point in a reasonable format. Recompile your class and correct any errors reported by the compiler. Enter the code for that method here.


 
 
 
 
 
 
 
 
 
 
 
 
 
 

Step 3. Create a TestMyPoint class with a main method that creates a MyPoint and asks it to print itself out. Compile and execute TestMyPoint. What values are printed for the x and y coordinates? Why do you think this is?


 
 
 

If you encounter problems with this step, please read the notes on this problem.

Step 4. Create a setLocation(int x, int y) method for the MyPoint class. This method will set the xcoordinate and ycoordinate fields to the corresponding parameters. Recompile MyPoint and correct any compiler errors.

Extend TestMyPoint to test this method by setting the x coordinate to 2 and the y coordinate to 3 and then asking the point to print itself. Recompile and run TestMyPoint and correct any errors.

Enter the code for the setLocation method here.


 
 
 
 
 
 
 
 
 
 
 
 
 
 

Experiment J3.4: Constructors

Required code files:

Step 1. Create a constructor for the PointPrinter class that takes no parameters and initializes any fields to appropriate values. Recompile PointPrinter and execute PointFun. What happens? Is that what you expected? Why or why not?


 
 
 
 
 
 

Step 2. In step 1, you recompiled PointPrinter but executed PointFun. Why didn't you need to recompile PointFun?


 
 
 

Step 3. Create a one-parameter constructor for the PointPrinter class that initializes the count of points printed. (Do not delete your other constructor!) Recompile PointPrinter and correct any errors. Enter your code for the constructor here.


 
 
 
 
 
 

Step 4. PointFun to use that constructor and to use 100 as the first value. Recompile and execute PointFun. Did the modifications have the expected impact?


 
 
 

Step 5. Update PointFun to use a zero-parameter constructor, as in

    PointPrinter printer = new PointPrinter();

Recompile and test. What happens? Is that what you expected? Why or why not?


 
 
 
 
 
 

Step 6. Delete the zero-parameter constructor for the PointPrinter class (leaving you with just the one-parameter constructor). Recompile PointPrinter and try to execute PointFun (you should not need to recompile PointFun). What happens? Is that what you expected? Why or why not?


 
 
 

Step 7. Delete the one-parameter constructor for the PointPrinter class (leaving you with no constructors). Recompile PointPrinter and try to execute PointFun (you should not need to recompile PointFun, but you may do so if you wish). What happens? Is this the same as in the previous step? Why or why not?


 
 
 
 
 
 

Experiment J3.5: Constructors, revisited

Required code files:

Step 1. Create a constructor for the MyPoint class that takes two parameters: the initial x value and the initial y value. Recompile MyPoint and correct any errors.

Update TestMyPoint to use that constructor (and only that constructor). For example, you might write

    MyPoint pt = new MyPoint(2,3);

Recompile and run TestMyPoint.

Enter your code for the constructor here.


 
 
 
 
 
 

Step 2.

Update TestMyPoint to use a parameterless constructor for MyPoint. For example, you might write

MyPoint pt2 = new MyPoint();

What happens when you try to compile and run TestMyPoint? Why?


 
 
 

Step 3. Create a parameterless constructor for MyPoint that initializes both coordinates to 0. Recompile MyPoint and correct any errors. What happens when you try to compile and run TestMyPoint? Is your result the same as or different from the result in Step 2? Why?


 
 
 
 
 
 

Step 4. Make a copy of MyPoint named MyPt (when making the copy, you will need to change the file name to MyPt.java and the class name to MyPt). Try to compile the new class. What happens? Why? How can you correct that problem?


 
 
 
 
 
 

Experiment J3.6: Overloading read methods

Required files:

Before you begin, make a copy of Point.java, PointReader.java, and PointPrinter.java. Compile the three files.

Step 1. Make a copy of ReadTester.java, which contains


import SimpleInput;
import SimpleOutput;
import Point;
import PointReader;
import PointPrinter;

/**
 * A simple test of the various methods provided by the PointReader
 * class.  Used as an illustration of method overloading.
 */
public class ReadTester {
  /**
   * Run the thrilling tests.
   */
  public static void main(String[] args) {
    SimpleInput in = new SimpleInput();
    SimpleOutput out = new SimpleOutput();
    PointReader reader = new PointReader();
    PointPrinter printer = new PointPrinter();
    Point pt = reader.read(out,in);
    printer.print(out,pt);
  } // main(String[])
} // class ReadTester


Compile and execute ReadTester. Record the output.


 
 
 

Step 2. Add the following lines to the main method of ReadTester.

    // Step 2.  Read a point without prompting.
    pt = reader.read(in);
    printer.print(out,pt);

What do you expect to happen when you compile the modified ReadTester class?


 
 
 

Step 3. Attempt to compile the modified ReadTester. Record any errors. What do these errors suggest?


 
 
 
 
 
 

Step 4. Add the following method to PointReader.

  /**
   * Read a point without prompting.
   */
  public static Point read(SimpleInput in) {
    float x;	// The x coordinate.
    float y;	// The y coordinate.
    x = in.readFloat();
    y = in.readFloat();
    return new Point(x,y);
  } // read(SimpleInput)

What do you expect to happen when you compile the modified PointReader class?


 
 
 

After entering your answer, compile the modified class and correct any errors.

Step 5. What do you expect to happen when you now try to compile ReadTester?


 
 
 

After entering your answer, compile the modified class.

Step 6. Execute ReadTester and record the results. Note that you will have to enter the two components of the second point without being prompted.


 
 
 
 
 
 

Experiment J3.7: Overloading

Required files:

Before you begin, make sure you have a fresh copy of AverageComputer.java, which you should have created in a previous lab. If not, here is the code for it.


/**
 * Methods for averaging two numbers.  Intended as an illustration of function
 * return values.  Will also be used as an example of overloading.  Might also
 * be used as an example of overflow.
 *
 * @author Samuel A. Rebelsky
 * @version 1.0 of January 1999
 */
public class AverageComputer {
  /**
   * Compute the average of two doubles.
   */
  public double average(double a, double b) {
    return (a + b) / 2;
  } // average(double,double)
} // class AverageComputer


Also make sure that you have a copy of AverageTester.java.

Step 1. Compile the two files and execute AverageTester. When prompted for input, enter 2 and 3 and record the results.


 
 
 

Step 2. Add the following lines to the end of the main method of AverageTester.

    // Step 2.  Average two integers.
    int firstInt;
    int secondInt;
    out.print("Enter an integer: ");
    firstInt = in.readInt();
    out.print("Enter another integer: ");
    secondInt = in.readInt();
    out.println("The average of " + firstInt + " and " + secondInt + 
                " is " + computer.average(firstInt,secondInt));

What do you think will happen when you try to compile and execute the modified AverageTester? Why? If it executes successfully, what will the output be?


 
 
 
 
 
 

Step 3. Compile and execute the modified AverageTester, using 2 and 3 as the pair of numbers in each case. Record and explain the output. Pay close attention to differences in the output.


 
 
 
 
 
 

After recording your answer, you may wish to look at the notes on this problem.

Step 4. Add the following lines to the end of the main method of AverageTester.

    // Step 4.  Compute the average in a different way.
    out.print("That average might also be stated as ");
    out.println((firstInt + secondInt) / 2);

What do you expect the new output to be?


 
 
 

Step 5. Compile and execute the modified AverageTester, using 2 and 3 as the pair of numbers in each case. Record and explain the output.


 
 
 
 
 
 

After recording your answer, you may wish to look at the notes on this problem.

Step 6. Add the following method to AverageComputer.

  /**
   * Compute the average of two integers.
   */
  public int average(int a, int b) {
    return (a + b) / 2;
  } // average(int,int)

What effect, if any, do you expect this modification to have on the output of AverageTester?


 
 
 

Step 7. Recompile AverageComputer and AverageTester. (Even though you have not modified AverageTester, you should recompile it because you've overloaded a method it uses in AverageComputer.) Execute AverageTester. Enter 2 and 3 for each pair of numbers. Record your output. Does this output differ from that in step 5? If so, why?


 
 
 
 
 
 

After recording your answer, you may wish to look at the notes on this problem.

Step 8. Remove the average(int,int) method from AverageComputer. Then add the following methods to AverageComputer.

  /**
   * Compute the average of an integer and a double.
   */
  public double average(int a, double b) {
    return (a + b) / 2;
  } // average(int,double)

  /**
   * Compute the average of a double and an integer.
   */
  public double average(double a, int b) {
    return (a + b) / 2;
  } // average(double,int)

Do you expect this modification to have any effect on either program?


 
 
 

Step 9. Compile AverageComputer. If that succeeds, compile AverageTester. If that succeeds, execute AverageTester. What happened? Why?


 
 
 
 
 
 

After recording your answer, you may wish to look at the notes on this problem.

Experiment J3.8: Borders

Optional applet experiment

Required files:

Step 1. Make copies of borderedsquare.html and BorderedSquareApplet.java. Read the two files. In your own words, explain what should happen when your run the applet.


 
 
 

Step 2. Compile BorderedSquareApplet. Load the applet using borderedquare.html. Describe the output.


 
 
 

Step 3. What do you expect to happen if you paint the border before painting the main body of the square?


 
 
 

Confirm your answer by making the appropriate changes, recompiling BorderedSquareApplet, and reloading the applet.

Step 4. You may have noted that while the left and right borders appear correct, there is a gap between the black square and the red border on the right and bottom. It makes no difference whether we draw the border first or the outline first. Change the line that reads line that reads

    paintBrush.drawRect(4,4,42,42);

to read

    paintBrush.fillRect(4,4,42,42);

(This should now be the first rectangle you draw.) What effect do you expect this change to have?


 
 
 

Confirm your answer by making the appropriate changes, recompiling BorderedSquareApplet, and reloading the applet.

Step 5. Change the line that reads

    paintBrush.fillRect(4,4,42,42);

to read

    paintBrush.drawRect(4,4,41,41);

What effect do you expect this change to have?


 
 
 

Confirm your answer by making the appropriate changes, recompiling BorderedSquareApplet, and reloading the applet.

Step 6. Are there differences between the previous two solutions? If so, what are they? Does it matter whether the border is drawn first or second in either case?


 
 
 

Experiment J3.9: A bordered-square class

Optional applet experiment

Required files:

Step 1. Make copies of the three files. Explain, in your own words, what the role of each file is or might be. You may wish to compile certain files or load applets.


 
 
 
 
 
 

After recording your answer, you may wish to consult the notes on this problem.

Step 2. We already know how to paint a ``normal'' square. We use paintBrush.fillRect(...). How might we paint a bordered square we've just created called mySquare?


 
 
 

Step 3. In your own words, summarize the changes you'll need to make to BorderedSquare in order to support different colors, sizes, and positions of bordered squares.


 
 
 
 
 
 

Step 4. Add five fields to BorderedSquare:

Compile BorderedSquare and verify that you have declared the fields correctly. Once you have done so, record the field declarations here.


 
 
 
 
 
 

Step 5. Add a zero-argument constructor to BorderedSquare. This constructor should initialize all of the fields to reasonable default values. Once you verify that the construtor works correctly, enter the code for the constructor here.


 
 
 
 
 
 

Step 6. Update the paint method to paint the main body of the square (not the border), using the fields for the various information. Once you verify that the method works correctly, enter the code for the method here.


 
 
 
 
 
 

Step 7. Add a five-argument constructor to BorderedSquare. The constructor should take the form

  public BorderedSquare(
    int left, int top,
    int side,
    Color mainColor, Color border)
  {
    ...
  } // BorderedSquare(int,int,int,Color,Color)

Once you verify that the construtor works correctly, enter the code for the constructor here.


 
 
 
 
 
 

Step 8. Add the following lines to the paint method of BorderedSquareTester.

    BorderedSquare redblack = 
      new BorderedSquare(10,10,50,Color.red,Color.black);
    BorderedSquare blackred = 
      new BorderedSquare(80,20,30,Color.black,Color.red);
    redblack.paint(paintBrush);
    blackred.paint(paintBrush);

What effect will this change make?


 
 
 

Step 9. What changes must we make to the paint method of BorderedSquare in order for the border to appear? You may need to refer to the steps in this experiment and the previous experiment.


 
 
 

Step 10. What other methods would you recommend that we add to the BorderedSquare class. You might want to consider whether we should be able to change fields, move the square, or update colors.


 
 
 
 
 
 

Step 11. In your own words, what are the advantages of having a BorderedSquare class?


 
 
 


Copyright (c) 1998 Samuel A. Rebelsky. All rights reserved.

Source text last modified Tue Oct 26 12:27:07 1999.

This page generated on Tue Oct 26 15:37:25 1999 by Siteweaver.

Contact our webmaster at rebelsky@math.grin.edu