Chapter 8

<< Chapter 7 | HomeworkTrailIndex | Chapter 9 >>

Designing Classes


Chapter 8 Summary

Review Exercises

R8.1

Users place coins in a vending machine and select a product by pushing a button. If the inserted coins are sufficient to cover the purchase price of the product, the product is dispensed and change is given. Otherwise, the inserted coins are returned to the user.

What classes should you use to implement it?

R 8.6

Suppose a vending machine contains products, and users place coins into the vending machine to purchase products. Draw a UML diagram showing the dependencies between the classes VendingMachine, Coin, and Product

R 8.9

Classify (Accessor or Mutator) the methods of the class Scanner that are used in this book as accessors and mutators.

boolean hasNext() 
boolean hasNextDouble() 
boolean hasNextInt() 
boolean hasNextLine() 
String next() 
double nextDouble() 
int nextInt() 
String nextLine() 

Programming Exercises

For 8 points do P8.5, P8.6, P8.10, P8.11. For 9 points, add P8.7. For 10 Points add P8.8. For 11 out of 10, add A JUnit Class.

8.5 Write static methods

public static double sphereVolume(double r)
public static double sphereSurface(double r)
public static double cylinderVolume(double r, double h)
public static double cylinderSurface(double r, double h)
public static double coneVolume(double r, double h)
public static double coneSurface(double r, double h)

that compute the volume and surface area of a sphere with radius r, a cylinder with circular base with radius r and height h, and a cone with circular base with radius r and height h. Place them into a class Geometry. Then write a program that prompts the user for the values of r and h, calls the six methods, and prints the results. Here are some helpful formulas:
V_{sphere}=\frac{4}{3}\pi r^3
A_{sphere}=4\pi r^2
V_{cone}=\frac{\pi}{3} h r^2
A_{cone}=\pi r^2+\pi r \sqrt{r^2+h^2}
V_{cylinder}=\pi h r^2
A_{cylinder}=2\pi r^2+2\pi r h

Here is a sample program run:

Please enter the radius:
5
Please enter the height:
10
The volume of the sphere is: 523.5987755982989
The surface area of the sphere is: 314.1592653589793
The volume of the cylinder is: 785.3981633974483
The surface area of the cylinder is: 471.23889803846896
The volume of the cone is: 261.79938779914943
The surface area of the cone is: 254.160184615763

Your main class should be called GeometryCalculator85.

GeometryCalculator85.java

import java.util.Scanner;
/**
 * GeometryCalculator85 here.
 * 
 * @author Chris Thiel
 * @version 17 Nov 2009
 */
public class GeometryCalculator85
{
    public static double sphereVolume(double r)
    {
        return 0;
    }
    public static double sphereSurface(double r)
    {
        return 1;
    }
    public static double cylinderVolume(double r, double h)
    {
        return 3;
    }
    public static double cylinderSurface(double r, double h)
    {
        return 4;
    }
    public static double coneVolume(double r, double h){
        return (Math.PI/3.0)*h*r*r;

    }
    public static double coneSurface(double r, double h)
    {
        return Math.PI*r*r+Math.PI*r*Math.sqrt(r*r+h*h);
    }
    public static void main(String[] args)
    {
        Scanner in=new Scanner(System.in);
        System.out.println("Please enter the radius: ");
        String input=in.nextLine();
        double r=Double.parseDouble(input);
        System.out.println("Please enter the height: ");
        input=in.nextLine();
        double h=Double.parseDouble(input);
        System.out.println("The area of the cone is: "+coneSurface(r,h));
        System.out.println("The volume of the cone is: "+coneVolume(r,h));

    }
}

GeometryCalculator85Test.java (a JUnitTestClass)

public class GeometryCalculator85Test extends junit.framework.TestCase
{
	public void testConeAreaTest()
	{
		assertEquals(254.160184615763, GeometryCalculator85.coneSurface(5.0, 10.0));
	}
	public void testConeVolumeTest()
	{
		assertEquals(261.79938779914943, GeometryCalculator85.coneVolume(5.0, 10.0));
	}
	public void testCylinderAreaTest()
	{
		assertEquals(471.23889803846896, GeometryCalculator85.cylinderSurface(5.0, 10.0));
	}
	public void testCylinderVolumeTest()
	{
		assertEquals(785.3981633974483, GeometryCalculator85.cylinderVolume(5.0, 10.0));
	}
	public void testSphereAreaTest()
	{
		assertEquals(314.1592653589793, GeometryCalculator85.sphereSurface(5.0));
	}
	public void testSphereVolumeTest()
	{
		assertEquals(523.5987755982989, GeometryCalculator85.sphereVolume(5.0));
	}
}

P8.6.

Solve Exercise P8.5 by implementing classes Sphere, Cylinder, and Cone. Which approach is more object-oriented?

Here is a sample program run:

Please enter the radius:
5
Please enter the height:
10
The volume of the sphere is: 523.5987755982989
The surface area of the sphere is: 314.1592653589793
The volume of the cylinder is: 785.3981633974483
The surface area of the cylinder is: 471.23889803846896
The volume of the cone is: 261.79938779914943
The surface area of the cone is: 254.160184615763

Your main class should be called GeometryCalculator86.

P8.7.

Write methods

public static double perimeter(Ellipse2D.Double e);
public static double area(Ellipse2D.Double e);

that compute the area and the perimeter of the ellipse e. Add these methods to a class Geometry. The challenging part of this assignment is to find and implement an accurate formula for the perimeter. To help, use the API to find the width and height. The formulas involve HALF the major axis a and HALF the minor axis b.

A_{ellipse}\approx \pi a b
P_{ellipse} \approx 2\pi \sqrt{\frac{1}{2}(a^2+b^2)}

Why does it make sense to use a static method in this case?

Use the following class as your tester class:

import java.awt.geom.Ellipse2D;
/**
   This is a tester for the ellipse geometry methods.
*/
public class EllipseTester
{
   public static void main(String[] args)
   {
      Ellipse2D.Double e = new Ellipse2D.Double(100, 100, 200, 100);
      System.out.println("Area: " + Geometry.area(e));
      System.out.println("Expected: 15707.963267948966");
      System.out.println("Perimeter: " + Geometry.perimeter(e));
      System.out.println("Expected:  496.7294132898051");

   }
}

P8.8.

Write methods

public static double angle(Point2D.Double p, Point2D.Double q)
public static double slope(Point2D.Double p, Point2D.Double q)

that compute the angle between the x-axis and the line joining two points, measured in degrees, and the slope of that line. Add the methods to the class Geometry. Supply suitable preconditions (think about what input would cause an error). Why does it make sense to use a static method in this case?

Use the following class as your tester class:

import java.awt.geom.Point2D;

/**
   This program tests the methods to compute the slope and
   angle of a line.
*/
public class LineTester
{
   public static void main(String[] args)
   {
      Point2D.Double p = new Point2D.Double(1, 1);
      Point2D.Double q = new Point2D.Double(3, 0);

      System.out.println("Slope: " + Geometry.slope(p, q));
      System.out.println("Expected: -0.5");

      Point2D.Double r = new Point2D.Double(3, -1);

      System.out.println("Angle: " + Geometry.angle(p, r));
      System.out.println("Expected: -45");

   }
}

P8.10.

Write a method

public static int readInt(
      Scanner in, String prompt, String error, int min, int max)

that displays the prompt string, reads an integer, and tests whether it is between the minimum and maximum. If not, print an error message and repeat reading the input. Add the method to a class Input.

Use the following class as your main class:

import java. util.Scanner;

/**
   This program prints how old you'll be next year.
*/
public class AgePrinter
{
   public static void main(String[] args)
   {
      Scanner in = new Scanner(System.in);
      int age = Input.readInt(in, "Please enter your age",
         "Illegal Input--try again", 1, 150);
      System.out.println("Next year, you'll be " + (age + 1));
   }
}

P8.11.

Consider the following algorithm for computing x^n for an integer n. If n < 0, x^n is \frac{1}{x^{-n}}. If n is positive and even, then x^n = (x^{n/2})^2. If n is positive and odd, then x^n = x \cdot x^{n-1} . Implement a static method double intPower(double x, int n) that uses this algorithm. Add it to a class called Numeric.

Use the following class as your tester class:

/**
   This is a test driver for the intPower method.
*/
public class PowerTester
{
   public static void main(String[] args)
   {
      System.out.println(Numeric.intPower(0.1, 12));
      System.out.println("Expected: " + 1E-12);
      System.out.println(Numeric.intPower(2, 10));
      System.out.println("Expected: 1024");
      System.out.println(Numeric.intPower(-1, 1000));
      System.out.println("Expected: 1");
   }
}

Write a JUnit

Make a JUnit test class for an earlier Homework Programming Exercise, such as P5.5