× Introduction Basic Shapes Color More Shapes Variables System Variables Decision Making Functions Loops Arrays OOP OOP Examples JS projects P5.js Projects

Object-Oriented Programming(OOP)

What are Objects?

The ability to define functions as a way to organize and reuse code has been around since the very earliest programming languages, way back to the 1950s with languages like FORTRAN and COBOL. In the 1990s another paradigm (way of thinking) of programming gained popularity, it’s called Object-Oriented Programming (OOP for short). Most modern languages like p5.js, Python, Java,a nd C++ all support OOP.

To understand what OOP is all about, we first need to understand what an object is. In the real world, we are surrounded by objects every day, in fact, you are an object! Every object in our world has certain properties (that describe it) and certain behaviours (things it can do). For example, every human has properties such as height, weight, eye colour, etc.. and common behaviours like sleeping,eating, and coding.

In terms of programming, an object is a way of organizing code that combines related variables (properties) and functions (behaviours). Since just about anything in our world can be thought of in terms of its properties and behaviours this makes Object-Oriented Programming (OOP) a very natural way of simulatingthe real world in software.

What is a Class?

Before we can create objects for use in our program, we need to create what is called a class . A good analogy for a class is a cookie-cutter. A cookie-cutter is not a cookie, but it describes what a cookie will be like and can be used to create as many cookies as we need. In programming, a class is code that describes what objects of that class (called instances) will be like.

Building a Class:

As mentioned, before we can instantiate (i.e., create) objects in our code, we need to define a class; a template that describes the variables and functions that each object of that class (i.e., each instance) will have in common. Let’s build a classfor our ball one step at a time.

Step 1:

 class Ball {
   // We’ll put more code here in Step 2
 }
 

It starts with the keyword class followed by the name of the class we are defi ning,then empty { curly braces } for the body of our class. In terms of naming a class, all of the usual naming rules for variables and functions apply, but you’ll notice one important exception: Class names always start with an Uppercase letter. Thisis a convention that all programmers follow so that it is obvious when reading code that something is a class rather than a variable.

Step 2:

we need to add a special function called a constructor to the class. constructor is to define and initialize the properties (i.e., variables) that allobjects of the class will have.

 
class Ball{
 constructor(){
   this.ballX = 200;
   this.ballY =200;
   this.speedX = 2;
  }
    // We’ll put more code here in Step 3
}

When we define functions inside a class we do not include the keyword function.The constructor() function header, must be typed exactly as shown. p5js does not allow us to use a different name for this special-purpose function, although as we’ll see later it’s possible to add parameters.

All of the global variables are placed in the constructor function. The keyword this (followed by a dot .) is a required prefix for each variable assigned a starting value in the constructor() function. Any variable defined like this can be accessed by any function inside our class. In other words, these variables still have global scope.

Step 3:

Third, we need to add a function for each behaviour we want objects of this class to exhibit.

class Ball {
  constructor() {
    this.ballX = 200
    this.ballY = 200
    this.speedX = 2
  }
  
  display() {
    // Draw the ball
    fill(255, 255, 0)
    ellipse(this.ballX, this.ballY, 40, 40)  
  }
  
  bounce() {
    // Reverse direction if we've hit a canvas edge
    if (this.ballX > width || this.ballX < 0) {
      this.speedX = this.speedX * -1
    }
  }
  move() {
    // Change the x location of the ball
    this.ballX = this.ballX + this.speedX
  }
}

display(), bounce(), and move() functions are all indented inside the { body } of the Ball class and that the keyword function is not used. Also, notice that every time we refer to one of the variables declared in the constructor, we must prefix its name with the keyword this followed by a dot (.)

That’s actually all there is to defining a simple class. However! At this point, we have not instantiated (created) any objects of the class that we can use in our code.

Step 4:

Next, we need to instantiate one (or more) objects of our class in a program.

let myBall
function setup() {
  createCanvas(400, 400)
  myBall = new Ball()
}

myBall is a global variable that we’ll use to refer to a Ball object. Since we only want to create a Ball object once when the program starts, I instantiate a new Ball object inside setup(). The new keyword automatically calls the constructor() function to initialize the variables for a new Ball object being instantiated. The assignment (=) operator sets the myBall variable to refer to the new Ball object in memory.

Step 5:

Finally, now that we have instantiated a Ball object and have a variable to refer to it, we can interact with the object by calling its functions, as shown here in the draw() function:

function draw() {
  background(220)
  myBall.display()
  myBall.bounce()
  myBall.move()
}

To call the functions within the object you must prefix the name of the function you are trying to call with the variable name we are using to refer to the object followed by a dot (.). This is called dot-notation in OOP.

The Complete Code

For reference, here’s the complete program with everything included together.

let myBall

function setup() {
  createCanvas(400, 400)
  myBall = new Ball()
}

function draw() {
  background(220)
  myBall.display()
  myBall.bounce()
  myBall.move()
}

class Ball {
  constructor() {
    this.ballX = 200
    this.ballY = 200
    this.speedX = 2
  }
  
  display() {
    // Draw the ball
    fill(255, 255, 0)
    ellipse(this.ballX, this.ballY, 40, 40)  
  }
  
  bounce() {
    // Reverse direction if we've hit a canvas edge
    if (this.ballX > width || this.ballX < 0) {
      this.speedX = this.speedX * -1
    }
  }
  move() {
    // Change the x location of the ball
    this.ballX = this.ballX + this.speedX
  }
}