11: Objects and Classes

Introduction

Objects can be one of the most difficult programming concepts to understand. Once it clicks, however, it really clicks. I recommend you read and pay close attention to the textbook, and utilize your resources until you understand objects and classes, as your upcoming evaluation will rely heavily on your understanding of these concepts.

Before you begin, please read the Python documentation 9.2. Python Scopes and Namespaces. This stuff messes a lot of people up during major labs!

Let’s get started.

A Metaphor

Classes are like a blueprint. They describe the traits and actions of something. Let’s look at a real life example, using a car.

To generalize our example, we will define a car as a vehicle with four wheels and an engine. We know, however, that some cars are different. Some are different colours, or seat more passengers. Our class describes the object in general. For example:

Class: Car

The class definition of colour simply states:
  The car has a colour.

And for our number of passengers:
  The car seats some number of passengers.

Objects are created using the “class” blueprints. So, let’s say we want to build a blue car that seats 5 people. We can then fill in the blanks from our class design to create the object defined as having the colour blue, and room for 5 passengers. We’ll call this car something different than the class name. This is because we want it to be identifiable. We’ll call it MyCar.

Formal Definition

To stick with the terms you’ll be required to know, here’s a formal definition of what we just described. Read it slowly and make sure you understand it!

“MyCar” is an object. This object is an instance of the class “Car”. The class defines two attributes, colour, and number of passengers. Both of which can be defined specifically for each instance of “Car”.

Class Definition

Here’s the basic Python syntax for defining a class:

# Simple class definition 
class ClassName: 
    <statement 1> 
    . . . 
    <statement N>

There are a few different types of statements that we will use to create our class. I’m going to try to cover all the “types” of statements, but there are many different applications for these, which I will leave up to you.

Defining Attributes

In our car example, we decided that every car needs a colour. This colour can (though it does not have to be) be unique for each instance of “Car”. When we initialize an object with certain data, that is called an Attribute.

An Attribute is a piece of data that describes the object. Since our class definition just gives us a blueprint for the object, we need to define attributes to describe the specific instance of the class in a bit more detail.

Attributes are usually defined when we create the object. This is done using Python’s special initialization function __init__. (TWO underscores before and after the word “init”)

The init function is called once when the object is first created and takes a few arguments. One is “self”, which always comes first, and we will discuss later. The other two are the parameters that we will be using to specify colour and the number of passengers that the car holds.

When we save attributes, we want to assign them to “self”. This is because of the way that Python handles objects. We can think of it as the actual object running the code. Therefore, when we give it a colour, it has to think:

“Hey, this is MY colour, I’ll save it for my self.

class Car: 
    def __init__(self, colour, numOfPassengers): 
        # This is my colour 
        self.colour = colour 
        # This is my numOfPassengers 
        self.numOfPassengers = numOfPassengers

Accessors (Get Methods)

Once we’ve stored attributes, we will often need to get them back from the object. In the Vector example you’ve seen in lab, you need to be able to get the x and y coordinates to really make use of the class. Therefore, you will need to create a method that returns the values you’ll need to work with. We’ll apply this to our Car example, noting that we might need to check the colour of the car, or the number of passengers it seats.

class Car: def __init__(self, colour, numOfPassengers): 
    # This is my colour 
    self.colour = colour

    # This is my numOfPassengers 
    self.numOfPassengers = numOfPassengers 

    # GET methods 
    def getColour(self): 
        return self.colour 

    def getNumOfPassengers(self): 
        return self.numOfPassengers

Now how do we use these functions? The syntax for Objects and their methods is extremely important. Please make sure you understand this!

In general, the syntax for an object’s instance is:

Object.Method(arguments)

This calls Method from Object’s Class description, and passes it the arguments if necessary. self is always passed first, and this is done automatically. Do not pass it in, Python will handle that.

Defining Functions

Depending on your object class, you will often need it to perform more actions. This can be done by defining additional functions in the same way as we did above. These functions can do anything! They’re just like normal functions, but must still take in self in order to operate correctly. The syntax for all functions you will define in an object is:

class Object: 
    def myFunction(self, arg1, arg2... argN): 
        # Do something

self is determined when you call the function as follows:

 myObject = Object() 
 myObject.myFunction(arg1, arg2... argN)
#[-self-][-method--][-arguments--------] 

So if our function does anything to self, it is actually performing this action on the instance anObject. I’ve decided to go a bit more in depth about the self concept. It continues below. All you need to know is how to define object functions, and how to call them properly using Python syntax.

The “Self” Concept

No, this isn’t philosophy class. The concept of self in object oriented programming is possibly one of the most important concepts to understand. I’m going to do my best to describe it using a few methods and metaphors. Please let me know if it is unclear. Read this next part several times if you need to.

Self is a concept used in Python to describe the “current object”. When you call an object’s method:

 myObject.myMethod(argument1, argument2)

You can think of it as instructing myObject to perform the action myMethod using the variables argument1 and argument2. When Python goes to look at the code for myMethod, it goes straight to the Class definition (the blueprint). If we didn’t pass self, Python doesn’t know which object we’re talking about. When we use self, the identity of myObject is passed, so when Python checks the code for myMethod, it can see myMethod is utilizing some attribute of self, and in turn, is utilizing some attribute of myObject. An example from the lab follows:

class Vector: 
    def __init__(self, x, y): 
        self.x= x 
        self.y= y

Let’s start here.

Python passes in self so that it is in our scope. Otherwise, we would get an error saying it isn’t defined. When we use the statement self.x = x, we are saying “the value of x specific to this object is set equal to the parameter passed in”. This is basically a way of saving information inside our objects.

class Vector: 
    def __init__(self, x, y): 
        self.x= x 
        self.y= y def 

    getX(self): 
        return self.x def 
    getY(self): 
        return self.y

Here, we add two functions to get our x and y values. Python automatically passes the parameter self based on how the function was called. For example:

# Returns the x value from vector 1 
# In this case, self is the "vector1" object 
vector1.getX() 
# Returns the x value from vector 2 
# self is the "vector2" object 
vector2.getX()

This helps Python determine which value of x we’re returning. Remember that self doesn’t come out of nowhere. It is determined outside the class when you’re actually working with the methods of an instance of that class.

If we just told Python to getX(), there is no way for Python to know what we want. This will return an error, and this is exactly why we require the specific syntax for calling methods of objects:

 Object.Method(args)

Hopefully this clears things up. Your textbook’s chapter on this content is really well done, and I recommend reading it (I know it’s dry, but it’s worth it, I promise!) if you’re still struggling with this understanding. Next major lab will absolutely require you to understand these concepts, so make sure you know them!