CS102 Lab03 - Get into Shape

Design, implement and explore simple class hierarchies, abstract classes and interfaces.

Note: This assignment has nothing to do with drawing graphics in Java, everything is done on the console as usual! Create one JCreator project for part (1) and another for part (2), both within the same workspace.

  1. Shape up
    • Design a class hierarchy to include classes Shape, Rectangle (with width and height), Circle (with int radius) and Square (with int side). Shape should be abstract with method double getArea() and Square should inherit getArea() from Rectangle.
    • Create another class, ShapeContainer, to hold a set of shapes. It should have methods void add(Shape s), double getArea(), and String toString().
    • Write a ShapeTester class with a menu that allows the user to:
      • create an empty set of shapes (ShapeContainer),
      • add as many circle and rectangle shapes to it as they wish,
      • compute & print out the total surface area of the entire set of shapes, and
      • print out information about all of the shapes in the container by calling the toString() method for each shape.
    • Experiment. Try to predict what would happen when you (i) comment out the getArea() method of the Circle class, and (ii) also make the Circle class abstract, before finally (iii) creating an instance of the (now abstract) Circle class to add to the shapes collection. Test your predictions.
    • [New for Lab3ext] The customer is impressed with your work so far, and so asks you to extend the program. They want Shapes to be locatable (i.e., to have an x, y location, and getX(), getY() and setLocation(x, y) methods). As a good designer you decide to first create a Locatable interface with these methods, then have the Shape class implement it. In this way all shapes automatically become locatable. Add new options to your ShapeTester menu that allows the user to set the locations for shapes. Update the toString method to show the location of shapes.
    • [New for Lab3ext] The customer further asks you to add a method move(dx, dy) in order to move a shape dx units on the x-axis and dy unit on the y-axis. Create a Movable interface to implement this. Add a new option to your ShapeTester menu that allows the user to move shapes.
    • [New for Lab3ext] Impressed, the customer wants even more! This time they ask for shapes to be Selectable, so you again start by creating a Java interface, having boolean getSelected() and void setSelected(boolean) and boolean contains(int x, int y). Unfortunately, this time–for some unknown reason–you are not allowed to change the Shape class. Modify your other classes so that each shape added to the ShapeContainer is Selectable. Change the toString() methods so that they show whether the shape is selected or not. Add another option to your ShapeTester menu that allows the user to find the first Shape that contains a given x, y point and toggle its selected state. Provide another menu option that removes all selected shapes from the set of shapes.
  2. - Iterating IntBags
    • The Java API includes an interface called Iterator that is designed to retrieve each of the objects from a set of objects, once and once only. This allows programs to process each item in the set without being aware of the underlying implementation (which means it can be changed at will without affecting the client program). Your task is to provide this interface for your IntBag class.
      • Note: The IntBag class was designed to store primitive int types, rather than Java Object types. Since the Iterator next() method must return an Object, you will need to return the corresponding int in an Integer wrapper. Clearly, this is not an entirely satisfactory solution and you might consider extending Iterator to produce IntIterator, which provides an additional int nextInt() method.
    • There are several ways you might think of coding this problem. Clearly you must have a value (say index) that keeps track of position of the next item to be retrieved from the IntBag collection. This must be initialized to zero when an iteration begins, and be incremented each time a call is made to get the next element (such call returning the element at the index location within the set.) The hasNext() method simply determines whether the index value is less than the number of elements in the set or not. Putting this code inside the IntBag class is problematic; how can index be reset to zero so that the elements can be iterated through several times, and how can multiple independent iterations through the set be managed?
      • A simple solution to this is to write a new class, say, IntBagIterator, which implements Iterator. This class need have only two properties; bag (a reference to the IntBag set it is to iterate through) and index (the position of the next element to return from the bag). Code this class.
      • Test it using a class, TestIterators, which contains the following code,
            Iterator i = new IntBagIterator(bag);
            while (i.hasNext()) {
                System.out.println(i.next());
                Iterator j = new IntBagIterator(bag);
                // Iterator j = bag.iterator(); 
                while (j.hasNext())
                    System.out.println("--"+j.next());
            }
      • Notice that i and j are of the interface type, Iterator. This is valid since IntBagIterator implements Iterator and so is an Iterator.
      • Finally, add a method Iterator iterator() to your IntBag class. This should create an instance of IntBagIterator and return it as the interface type. Test this method by uncommenting the commented line in the above code and commenting out the line above it.
      • Java's ArrayList class has a similar method that allows you to iterate through its elements. Interestingly, there is no (immediately obvious) class in the Java API that corresponds to our IntBagIterator class. It actually has such a class, but nested inside ArrayList. The curious might like to read up on nested classes and perhaps even examine the Java source code for the ArrayList class to see how they did it!