CS46A Lab

Interfaces

Copyright © Cay S. Horstmann, Kathleen O’Brien 2009-2016 Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Put the answers to the questions in each step into the lab report. Copy/paste the programs that you write in the lab.

This icon indicates optional tasks. Do those if you have time. You may not leave early unless the optional parts are done

Part A: The Drawable Interface

  1. This is a project you watched in the videos. We are going to do it here for more practice. Download this code and unzip it into a lab13b folder.

  2. Double click on package.blue to open the project.
  3. Modify the program so that it can draw an arbitrary number of cars:

    Run your program to check that it draws the cars. Add the source code of the Neighborhood class to driver's lab report.

  4. We have implemented several classes for drawing shapes: cars, houses, dogs, and so on. They all have something in common: a method
    public void draw()
  5. We are going to create an interface Drawable so that we can put everything that implements the interface and has a draw method into one ArrayList and draw them all with one loop.

    Make an interface Drawable that declares a single method draw.

  6. That wasn't very exciting. Nothing different happened. We didn't make use of the fact that Car, Dog, and House (and potentially other classes) implement a common interface.

    Change the Neighborhood.java as follows:

    Run your program to check that it draws everything correctly. The picture still looks the same but your Neighborhood.java class is more compact.

    Driver: Add the source code of the Neighborhood class to your lab report.

  7. Look at the drawing code in Neighborhood again. It should contain code similar to
    for (Drawable d : drawables)
       d.draw();

    Scribe: How does the compiler know that d (or whatever you called it) has a draw method?

  8. Look at the code where you add objects to the ArrayList again. It should contain code similar to
    drawables.add(new Car(30, 40));

    But drawables is not an ArrayList<Car>. It is an ArrayList<Drawable>. Scribe: Why is it legal to add a Car?

    Because each Car object belongs to a class that implements Drawable. It is a type of Drawable!

  9. Create a class Ball (File > New > Class ...) that also implements the Drawable interface. It needs a constructor that takes x, y coordinates and instance variables to store them in. Its draw method should look like
     public void draw()
     {
         final int DIAMETER = 40;
         Ellipse shape = new Ellipse( x, y, DIAMETER, DIAMETER);
         shape.setColor(Color.RED);
         shape.fill();
     }

    Add a few balls to the drawables array list. Run your program.

    Upload a screen shot with cars, dogs, houses, and balls with your lab report.

Part B: The Moveable Interface

  1. Some objects move, for example cars and dogs. Make a new interface
    public interface Moveable
    {
       void move(int seconds);
    }

    This tells the object how many seconds to move. Have the Car and Dog classes (but not the House class) implement the Moveable interface in addition to the Drawable interface. Simply add a comma and Moveable to the class declarations.

    public class Car implements Drawable, Moveable
    Do something similar with the Dog class.

    Compile your code. Scribe: What happens? Why?
  2. You need to provide the method that the interface required. For now, we'll just have cars move horizontally and dogs move vertically.
  3. For the Dog class, add this move method which will move the dog 2 pixels in the y direction for each time it is called
       public void move(int seconds)
       {
          final int SPEED = 2; // pixels per second
          pic.translate(0, SPEED * seconds);
          name.translate(0, SPEED * seconds);
       }
  4. For the Car class, use this move method which moves the car 10 pixels for each call.
       public void move(int seconds)
        {
            final int SPEED = 10; // pixels per second
            body.translate(seconds * SPEED, 0);
            frontTire.translate(seconds * SPEED, 0);
            rearTire.translate(seconds * SPEED, 0);
            frontWindshield.translate(seconds * SPEED, 0);
            roofTop.translate(seconds * SPEED, 0);
            rearWindshield.translate(seconds * SPEED, 0);
        }
  5. Of course, nothing is moving yet. In main method of Neighborhood, make the following change. Right after the loop that draws the objects, add these lines. This will loop through the drawables array list 10 times, calling the move method for everything that moves
          for (int i = 1; i <= 10; i++)
          {
             for (Drawable d : drawables)
             {
                // TODO: Move those elements that are moveable for 1 second each
                if (d instanceof Moveable)
                {
    
                   d.move(2);
                }
                Canvas.snapshot();
             }
          }

    Compile. Scribe: What happens? Why?

  6. The compiler refuses to call move on a variable that isn't of type Moveable. The variable d is type Drawable not Moveable even though the object is also a Moveable as well as a Drawable. Here, we need to use a cast. Replace the call to move with these lines
    Moveable m = (Moveable) d;
    m.move(2);
    

    The cast is safe because we already checked that d instanceof Moveable. Using the cast assigns the object to a Moveable reference variable. We can call move on that type of variable. Compile to make sure you don't get any errors.

    Driver: What is your main method now?

Part C: Homework11

Part D: ParFinalExam