Week 5 -- Data and Functionality, together at last. . .

back to syllabus

Object Oriented Design

"The term object-oriented design refers to the art of decomposing an application into some number of objects, self-contained application components that work together. The goal is to break your problem down into a number of smaller problems that are simpler and easier to handle and maintain."
-- Learning Java, Neimeyer, Knudsen

Let's say we were writing a program that simulates a car race (with just one car). Before today our pseudo-code might have looked something like this.
Data:
Car color.
Car x location.
Car y location.
Car x velocity.
Car y velocity.
Car x acceleration.
Car y acceleration.

Setup:
Initialize car color.
Initialize car location to starting point.
Initialize car velocity.
Initialize car acceleration.

Loop:
adjust velocity by acceleration
adjust location by velocity
Paint background
draw car at location with color

This is all well and good. Nevertheless, using all these variables might become more and more unpleasant as we expand and adjust our program. We can do better. We can create a car "object" that holds onto all the data for the car (color, location, velocity, acceleration). The real magic, though, is not in the data. . It's in the functionality. The car not only had a set of data associated with it. In addition, it has a set of fucntions. In other words, we can say: "Drive the car" or "Draw the Car", etc.

Therefore, using our object-oriented design, our pseudo-code might look something like this:
Data:
Car object

Setup:
Initialize car object

Loop:
Paint Background
Accelerate car
Drive car
Draw car
Our code becomes much simpler. All the work is now done inside each object (note i've left out the code for the actual Car "class" for the time being)

Let's take a look at what the actual body of our program might look like.
Car c;

void setup() {
  c = new Car(**parameters go here**);
}

void loop() {
  background(0);
  c.draw();
  c.accelerate();
  c.drive();
}
Here, we have a variable of type "Car." Just like we have variables of type int, float, color, etc., we've now established a new type. However, in order to be able to use a variable of this type, we first need to create an object "class".

Classes

In processing, a class is a "blueprint" or "template" for the creation of an object. To write our class, we must do the following:

  • name the class -- this is done by saying "class objectName". As always, we then enclose the code for the class in curly brackets.
  • declare instance variables for the class -- these are variables that will hold onto the data associated with each instance of an object born from our template.
  • declare a constructor -- The constructor is a method that always has the same name as the class. It specifies any required parameters for creating an "instance" of the object. (Note that an object can have more than one constructor.) For example, if we want to make a new car, we must "construct" one based on a set of parameters (color, size, location, etc.)
  • write any necessary functions -- we can add functionality to our object by writing methods. These are done in the same way as described in week 4 -- return type, function name, function parameters, function code.

    Here's how the code looks:
    class Car
    {
    
      color c;
      int xpos;
      int ypos;
      int xvel;
    
      //****CONSTRUCTOR*****//
      Car(color c_, int xp, int yp, int xv) {
        c = c_;
        xpos = xp;
        ypos = yp;
        xvel = xv;
      }
    
      void draw () {
        rectMode(CENTER_DIAMETER);
        fill(c);
        rect(xpos,ypos,20,10);
      }
    
      void drive () {
        xpos = xpos + xvel;
        if (xpos > width) { xpos = 0; }
      }
    }
    

    Instance of an object

    An instance of an object is declared in the same way that we declare a variable. We specify the data type (the class name) and the variable name (whatever we choose).
    Car myCar;
    
    The above indicates that we're going to have a variable named "myCar" of type "Car" (and this is an acceptable type because we've presumably set-up a class entitled "Car"). An object is then allocated using the new operator. The argument to new is the constructor for the class.
    Car myCar = new Car();
    
    In this case, however, we want pass some arguments to the constructor to specify information about the kind of car we want to create (its color, x location, y location, and speed.)
    color tempcolor = color(255,0,0);
    Car myCar = new Car(tempcolor,0,50,1);
    
    In the body of our code, we can now call on various functions associated with the object. To do this, we first write the variable name that holds the reference to our object, then a dot ('.'), then the name of the function, i.e.
    myCar.drive();
    myCar.draw();
    
    Let's look at an example, where we create two instances of our car object.


    Car myCar1;
    Car myCar2;
    
    void setup() {
      size(100,100);
      colorMode(RGB,255,255,255,100);
      color tempcolor = color(255,0,0);
      myCar1 = new Car(tempcolor,0,50,1);
      tempcolor = color(0,255,0);
      myCar2 = new Car(tempcolor,0,75,2);
    }
    
    void loop() {
      background(0);
      myCar1.draw();
      myCar2.draw();
      myCar1.drive();
      myCar2.drive();
    }
    
    class Car
    {
    
      color c;
      int xpos;
      int ypos;
      int xvel;
    
      //****CONSTRUCTOR*****//
      Car(color c_, int xp, int yp, int xv) {
        c = c_;
        xpos = xp;
        ypos = yp;
        xvel = xv;
      }
    
      void draw () {
        rectMode(CENTER_DIAMETER);
        fill(c);
        rect(xpos,ypos,20,10);
      }
    
      void drive () {
        xpos = xpos + xvel;
        if (xpos > width+20) { xpos = -20; }
      }
    }
    
    Now, let's expand on this idea and make an array of our objects.


    int MAX = 200;
    //declare array of Cars
    Car[] myCars = new Car[MAX];
    
    void setup() {
      size(200,200);
      //set colorMode
      colorMode(RGB,255,255,255,100);
      //fill array of cars using "New" -- all cars are random color, random y location
      for (int i = 0; i < MAX; i++) {
        color tempcolor = color(random(255),random(255),random(255), random(100));
        myCars[i] = new Car(tempcolor,0,random(height),random(1,5));
      }
    }
    
    void loop() {
      background(0);
      //for every car in the myCars array, call the drive and draw functions
      for (int i = 0; i < MAX; i++) {
        myCars[i].drive();
        myCars[i].draw();
      }
    }
    
    class Car
    {
    
      color c;
      float xpos;
      float ypos;
      float xvel;
    
      //****CONSTRUCTOR*****//
      Car(color c_, float xp, float yp, float xv) {
        c = c_;
        xpos = xp;
        ypos = yp;
        xvel = xv;
      }
    
      void draw () {
        rectMode(CENTER_DIAMETER);
        fill(c);
        noStroke();
        rect(xpos,ypos,20,10);
      }
    
      void drive () {
        xpos = xpos + xvel;
      if (xpos > width+20) { xpos = -20; }
      }
    }
    
    Click here for another more advanced example of using an object in processing -- uses sine and cosine

    Related Examples from the Processing Web Site

    objects
    scrollbar
    springs

    back to syllabus