Top: Index Previous: Loops and Refactoring Up: Index Next: Arrays and Exceptions

CSC8303 -- Bioinformatics Programming in Java

Conditionals and inheritance

The purpose of this exercise is:

exclaim
  • For you to gain familiarity with conditional statements.
  • Introduce the idea of inheritance.
  • To gain familiarity with the use of arrays.

If statements

It's not enough to be able to loop, we need code that sometimes does one thing and sometimes does another. Hence the if statement.

act
  • Write a class with a body like this:
public class Bounce{

    public void animateBouncingCircle(){

        Circle c = new Circle();
        c.makeVisible();

        // the canvas is 300 in size, and the circle is 30 in diameter. We
        // could hard-code this as 270 but this explains where the value comes
        // from.
        int maxSize = 300 - 30;

        for (int i = 0; i < getNumberOfSteps(); i++) {
            c.moveHorizontal(getHorizontalStep());
            c.moveVertical( getVerticalStep());
            animateStep();

        }
        eraseObject( c );
    }


    private int numberOfSteps;

    public int getNumberOfSteps() {
        return numberOfSteps;
    }

    public void setNumberOfSteps(int numberOfSteps) {
        this.numberOfSteps = numberOfSteps;
    }


    private int verticalStep;

    public int getVerticalStep() {
        return verticalStep;
    }

    public void setVerticalStep(int verticalStep) {
        this.verticalStep = verticalStep;
    }


    private int horizontalStep;
    public int getHorizontalStep() {
        return horizontalStep;
    }

    public void setHorizontalStep(int horizontalStep) {
        this.horizontalStep = horizontalStep;
    }
}

and another like this.

public class BounceTest {

    public static void main(String[] args) throws InterruptedException {

        Bounce b = new Bounce();
        b.setHorizontalStep( 1 );
        b.setVerticalStep( 2 );
        b.setNumberOfSteps( 2000 );

        b.animateBouncingCircle();

        Thread.currentThread().sleep( 2000 );
        System.exit( 0 );

    }
}
exclaim These classes should both be in the animate package. You will need to put import statements in place also. Your code will still not compile because you lack methods such as animateStep. Copy all the relevant methods from Grow.java until your code compiles.

This is fine, but the Circle falls of the edge of the Canvas which is not what we want. What would be nice is to change the direction of the Circle when it hits the edge. For this, we need two things. First, we need to know where the Circle object is and, second, we need a conditional statement.

act
  • Unfortunately, although the Circle objects know what their position is, there is no way to access this. So, first we need to change this class.
  • Add to Circle.java the following code:
    public int getXPosition(){
        return xPosition;
    }

    public int getYPosition(){
        return yPosition;
    }
  • This introduces two new methods to the Circle class; these are called accessor methods. They allow you to get the location information that was previously hidden.
  • Now, you need to introduce a if statement into this for loop.
     for (int i = 0; i < getNumberOfSteps(); i++) {
            c.moveHorizontal(getHorizontalStep());
            // check here if getXPosition has got too large.

            c.moveVertical( getVerticalStep());
            // check here if getYPosition has got too large.

            animateStep();

     }
  • At the points highlighted, you should introduce an if statement which checks to see if getXPosition() or getYPosition() have returned greater than maxSize. If yes, they should reverse their direction.
  • Run BounceTest.java again. Your circle should now bounce off the edge of the Canvas. However, when it reaches the left edge, it will disappear again.
  • Put another conditional check in, so that when getXPosition() or getYPosition() go below 0, they reverse direction.
  • It is possible to do this with another two if statements, or using only the existing ones. See if you can work out how.

Inheritance

Our code now works, so it's worth creating a copy of it, so that we can go back to this version if necessary. Next thing is to change it!

One problem is that some of the code appears in both Bounce.java and Grow.java. This is a pity; if we want to change the code, then we need to change it in two places. So we are going to use inheritance to get around this. You can read more about inheritance if you choose.

You should have three pieces of code in both places. We are going to move them to a new class called Animate.java.

act
  • Create a new java class called Animate.java.
  • Add in all of this code which you should have earlier copied from Bounce.java 1.
  private int animateStep;

    /**
     * Get the value of animateStep
     *
     * @return the value of animateStep
     */
    public int getAnimateStep() {
        return animateStep;
    }

    /**
     * Set the value of animateStep
     *
     * @param animateStep new value of animateStep
     */
    public void setAnimateStep(int animateStep) {
        this.animateStep = animateStep;
    }


    protected void animateStep() {
        Canvas.getCanvas().wait( 50 );
    }

    protected void eraseObject(Object erased) {
        Canvas.getCanvas().erase(erased);
    }
  • Delete this code from both Bounce.java and Grow.java. Grow.java should now be pretty small!
  • Now we have only got the code once, but we cannot compile; we've moved code away from these two classes, but not told them were it has gone.
  • Change the first line of Bounce.java to this.
public class Bounce extends Animate
  • This essentially tells Java "if you can't find something in Bounce.java look in Animate.java instead.
  • Change Grow.java also.

It is easy with this exercise to underestimate the importance of inheritance; all we have done is move code around, surely? But, we've also decreased the total amount of code, as it's now in Animate.java rather than both Bounce.java and Grow.java. With just two classes performing animation this is a small advantage, but if we had 20 it would be a big advantage. Effectively using the same code in two (or more) places is essential to modern programming.

As well as saving typing, it means that the code is more likely to be correct; if we find a bug, we only have to fix it in a single place. If we add more functionality to Animate.java, it's automatically available to all the other classes that extend it. So, for example, Windows 7 has some nice features for managing windows like "extend the window to half the screen size" — very useful if you have a big monitor. Every application built on windows gains this function automatically, without having to be changed.

Inheritance is one of the building blocks of "object orientation". It's not the only way to achieve code reuse, but it is very common. Please read the java tutorial if you didn't the first time.

logThe two new files — Bounce.java and BounceTest.java — and the two modified files Grow.java and GrowTest.java are coursework for this exercise.

1. There are two small changes to the original code which you should be able to find. Don't worry about these too much.


Top: Index Previous: Loops and Refactoring Up: Index Next: Arrays and Exceptions