CS 515 Java Tutorial #2

Consider the following questions. They may be discussed in recitation.
  1. Consider this code, and explain what is going on.
    1. what does "this" refer to?
    2. what does "?" mean?
    3. why won't this code compile?
    4. given several methods with the same name, how does the compiler know which one to call?
    public class Sphere {
      ... (same definitions as before) ...
    
      public static final int MAX_RADIUS = 10;
    
      void setRadius(int radius) {
        this.radius = radius;
      }
    
      void setRadius(double r) {
        radius = r;
      }
    
      boolean setRadius (double r) {
        if (r > MAX_RADIUS) {
          System.out.println("Max radius exceeded");
          return false;
        }
        else {
          radius = r;
          return true;
        }
      }
    
      public static void main (String[] args) {
        Sphere ball  = new Sphere(1);
        Sphere ball2 = new Sphere(2);
        boolean success = ball.setRadius(20.0);
        ball2.setRadius(5);
        System.out.println("set Radius succeeded? " +
                           success ? "yes" : "no");
      }
    }
    

  2. Exceptions: Consider the following code:
    public class Sphere {
      ... (same definitions as before) ...
    
      boolean setRadius(double radius) {
        if (r > MAX_RADIUS) {
          System.out.println("ERROR: Max radius exceeded");
          return false;
        }
        else {
          radius = r;
          return true;
        }
      }
    
      boolean expand(double scale) {
        if (setRadius(radius * scale)) {
          return true;
        }
        else {
          System.out.println("ERROR: Max radius exceeded on expand");
          return false;
        }
      }
    
      public static void main (String[] args) {
        Sphere ball  = new Sphere(1);
        if (!ball.expand(3.0)) {
          System.out.println("ERROR: Expand failed");
        }
      }
    }
    
    Consider this code instead:
    public class Sphere {
      ... (same definitions as before) ...
    
      void setRadius(double radius) throws Exception {
        if (r > MAX_RADIUS) {
          throw new Exception("ERROR: Max radius exceeded");
        }
        radius = r;
      }
     
      void expand(double scale) throws Exception {
        setRadius(radius * scale);
      }
    
      public static void main (String[] args) {
        Sphere ball  = new Sphere(1);
        try {
          ball.expand(3.0);
        }
        catch (Exception e) {
          System.out.println(e);
          throw new Error("expand failed");
        }
      }
    }
    
    1. explain why both programs do roughly the same thing.
    2. what exceptions are throw most often?
    3. what code can throw an exception?
    4. where can exceptions be caught?
    5. what happens if an exception is not caught?

    1. What's wrong with this code?
    2. Why does the compiler complain?
    3. How do you get it to shut up?
    public class Sphere {
      ... (same definitions as before) ...
    
      void setRadius(double radius) throws Exception {
        if (r > MAX_RADIUS) {
          throw new Exception("ERROR: Max radius exceeded");
        }
        radius = r;
      }
     
      void expand(double scale) throws Exception {
        setRadius(radius * scale);
      }
    
      public static void main (String[] args) {
        Sphere ball;
        try {
          ball = new Sphere(1);
          ball.expand(3.0);
        }
        catch (Exception e) {
          System.out.println(e);
        }
        System.out.println("ball is " + ball);
      }
    }
    

  3. Inheritance
    public class Sphere {
      ... (same definitions as before) ...
    }
    
    public class NamedSphere extends Sphere {
      String name;
    
      public NamedSphere(double radius) {
        name = "(none)";
        this.radius = radius;
      }
    
      public NamedSphere(double r, String name) {
        super(r);
        this.name = name;
      }
    
      public NamedSphere(String initialName) {
        name = initialName;
      }
    
      public String getName() {
        return name;
      }
    
      public String toString() {
        return name + ", " + super.toString();
      }
    
      public static void main (String[] args) {
        Sphere ball  = new Sphere(1);
        NamedSphere earth = new NamedSphere(6378, "Earth");
    
        System.out.println("ball is " + ball);
        System.out.println("earth is " + earth);
      }
    }
    
    1. what does "extends" mean?
    2. what does "super" mean?
    3. is "earth" an instance of Sphere?
    4. is "ball" an instance of NamedSphere?
    5. what is the second program's output?

    1. Explain what the cast (NamedSphere) does.
    2. Why is no cast needed for the "getRadius" call?
    3. What does the second program output?
    public class Sphere {
      ... (same definitions as before) ...
    }
    
    public class NamedSphere {
      ... (same definitions as before) ...
    
      public static void main (String[] args) {
        Sphere[] orbs = new Sphere[3];
        orbs[0] = new Sphere(1.0);
        orbs[1] = new NamedSphere(2.0, "two");
        orbs[2] = new NamedSphere(6378,"Earth");
    
        for (int i=0; i<3; i++) {
          Sphere s = orbs[i];
          if (s instanceof NamedSphere) {
            String name = ( (NamedSphere) s ).getName();
            System.out.println("orb [" + i + "] is called " + name);
          } 
          else {
            double radius = s.getRadius();
            System.out.println("orb [" + i + "] has radius " + radius);
          }
    
        for (int i=0; i<3; i++) {
          Sphere s = orbs[i];
          if (s instanceof Sphere) {
            double radius = s.getRadius();
            System.out.println("orb [" + i + "] has radius " + radius);
          } 
          else {
            String name = ( (NamedSphere) s ).getName();
            System.out.println("orb [" + i + "] is called " + name);
          }
       }
    }
    

  4. Objects versus primitives again:
    1. What is the output of this program?
    2. When is the error detected?
    public class Sphere {
      ... (same definitions as before) ...
    }
    
    public class NamedSphere {
      ... (same definitions as before) ...
    }
    
    public class Main {
      public static void main (String[] args) {
        Object[] things = new Object[3];
          things[0] = new Integer(42);
          things[1] = new Sphere(2.0);
          things[2] = new NamedSphere(6378, "Earth");
    
          for (int i=0; i<3; i++) {
            Object thing = things[i];
    	Class c = thing.getClass();
    	String name = c.getName();
    	Class s = c.getSuperclass();
    	String superName = s.getName();
    	System.out.println("thing[" + i + "] is a " + name
    	                   + " which extends " + superName);
          }
    
          for (int i=0; i<3; i++) {
            Integer theInt = (Integer) things[i];
    	int value = theInt.intValue();
    	System.out.println("thing[" + i + "]=" + value);
          }
       }
    }
    

  5. Abstract classes
    1. what makes Shape2D an abstract class?
    2. suggest a data structure problem where abstract classes are needed.
    public abstract class Shape2D {
      String name;
    
      public Shape2D(String name) {
        this.name = name;
      }
    
      public double getArea();
    }
    
    public class Square extends Shape2D {
      double width, height;
    
      public Square(String name, double w, double h) {
        super(name);
        width = w;
        height = h;
      }
    
      public double getArea() {
        return w * h;
      }
    }
        
    public class Circle extends Shape2D {
      double radius;
    
      public Square(String name, double r) {
        super(name);
        radius = r;
      }
    
      public double getArea() {
        return Math.PI * r*r;
      }
    }
    

  6. Abstract classes and multiple inheritance
    1. Explain what this code does.
    2. Under what situations will you need to use "implements"?
    public interface Comparable {
      public int compareTo(Object o);
    }
    
    public class Sphere implements Comparable {
      ... (same definitions as before) ...
    
      public int compareTo(Object o) {
        double diff = ((Sphere)o).radius > radius;
        if (diff > 0.0)
          return -1;
        else if (diff < 0.0)
          return +1;
        else
          return 0;
      }
    }
    

  7. Static methods and fields.
    1. What is the output of Test?
    2. how many copies of "radius" are created?
    3. how many copies of "totalVolume" are created?
    public class Sphere {
      ... (same definitions as before) ...
    
      public static int totalVolume = 0;
      double radius;
    
      public Sphere(double radius) {
        this.radius = radius;
        totalVolume += getVolume();
      }
    }
    
    public class Test {
      public static void main (String[] args) {
        for (int i=0; i<10; i++) {
          Sphere s = new Sphere(Math.random());
        }
        System.out.println("total vol = " + Sphere.totalVolume);
      }
    }
    

  8. Static methods and fields.
    1. What is wrong with this program?
    2. what is the "this" reference when getTotalVolume is called?
    public class Sphere {
      ... (same definitions as before) ...
    
      private static int totalVolume = 0;
      double radius;
    
      public Sphere(double radius) {
        this.radius = radius;
        totalVolume += getVolume();
      }
    
      public static double getTotalVolume() {
        System.out.println("radius="+radius);
        return totalVolume;
      }
    }
    
    public class Test {
      public static void main (String[] args) {
        for (int i=0; i<10; i++) {
          Sphere s = new Sphere(Math.random());
        }
        System.out.println("total vol = " + Sphere.getTotalVolume());
      }
    }
    

  9. Static methods and fields.
    1. Explain what is going on here.
    2. What is output by the program?
    3. Each time "accumulateVolume" is called, which Sphere does "s" refer to?
      
    public class Sphere {
      ... (same definitions as before) ...
    
      private static int totalVolume = 0;
      double radius;
    
      public Sphere(double radius) {
        this.radius = radius;
        accumulateVolume(this);
      }
    
      public static double accumulateVolume(Sphere s) {
        totalVolume += s.getVolume();
      }
    }
    
    public class Test {
      public static void main (String[] args) {
        for (int i=0; i<10; i++) {
          Sphere s = new Sphere(Math.random());
        }
        System.out.println("total vol = " + Sphere.getTotalVolume());
      }
    }