Object Oriented Programming


A class is a blueprint for an object. An object’s class is what defines its attributes and capabilities. Classes are made up of 3 main parts; attributes, constructors and methods.

Definition Syntax

Syntax overview for class declaration and definition:

Example of class declaration:

Creation Syntax

Initializing a composite data type requires constructing a new object. The general syntax for this is as follows:

Example of object creation:

attributes

Classes have attributes. Each object made from a class will have all the attributes established in that class. Additionally, each attribute in a class has a specific type. So, all objects we create from a certain class will contain all attributes defined in the class, and we can customize the values within these attributes for each individual object. For example:

The attributes declared inside the body of the TarHeel class are name, PID, and hatesDook. Every TarHeel object we make will have these attributes.

In this example, there are defualt values for each attribute of "", 0, true respectively. We can declare two new Tar Heels with all the default attributes as seen below:

attribute Access

To access an object’s attribute, just use the name of the object followed by the dot operator (.) followed by the attribute name.

For instance, the code above accesses first the PID attribute of student1 and then the hatesDook attribute of student2. We would expect this to print:

attribute Assignment

We can also use the dot operator (.) in order to reassign attributes of objects. Notice we have to specify which student we are referring to.

Now if we were to run the following:

It would output:

Constructors

Every class has a constructor. A class constructor specifies initial attributes of the class from outside of the class to create an instance of the class (also called an object of the class).

A constructor is a “magic” method because it is automagically called when the class is called.

In Python, methods of classes look very similar to functions, but they are defined inside of the class. A constructor is a method that every class has, and it requires specific syntax.

Example

Let’s stick with the TarHeel example:

The constructor always begins with def __init__ (self, parameters) and has no return type. The body of the constructor reassigns the class’s attributes to the values passed by the parameters. Let’s look at how this works by construction two new TarHeel objects:

We can still access an object’s attribute in the same way as before:

This will output:

We can still change attributes – now, student3’s name is “Baller”

But we cannot call an empty constructor.

Choosing what goes into the constructor

Notice that in the TarHeel constructor, we specifically initialized name and PID, but not hatesDook. Because all TarHeels hate dook, hatesDook can have a default value of True that does not need to be specified upon construction!

On the other hand, we know each TarHeel has a unique name and PID, so we want to specify these values in the class constructor.

Self

What is up with this self keyword? Essentially, self is assigned to a reference of the object you are working with on the heap. If you call a method on student3, for example, this will refer to the student3 object on the heap.

In the constructor, self.name references the name attribute of the self object. If we were constructing a new TarHeel object called student6, this would be student6’s name attribute.

Methods

Class methods are specific funtionality written for class instances within the classes themselves.

Syntax

Besides the first parameter of a method being self, a method’s syntax is the same as a function’s! Method syntax is as follows:

Calling a method

Once defined, a method can be called on any object of the class! To call a method, you use the dot operator, similar to how you access attributes of an object. Dissimilar, however, you end this call with double parentheses and any necessary arguments besides self!

General syntax is: ~~~ {.python} object.method_name(arguments) ~~~

Upon a method call, remember that self is automatically assigned to the object the method is being called on. While the method evaluates, self references the object on the heap!

Example

Let’s make a new class called Coffee:

In this class, we have 4 attributes, a constructor, and 3 methods! The methods make_decaf and remove_whip mutate attributes of the object they’re called upon, and the method call_customer returns a string unique to the object.

Let’s create some Coffee objects and call its methods to see what happens:

These last two lines will output:

Optional Parameters

Imagine you want to modify your Coffee class. You notice 80% of your customers order large coffees, so you want to simply your implementation to make each Coffee default to large. How could you do this?

The solution to your problem is making your parameters optional by assigning default values to specific parameters. Let’s look at our Coffee constructor.

If we want our coffee to default to large, we want to assign size a default value of large. A Coffee object can be specified to be small upon construction, but the size may also be left out to default the coffee size to large. Check out the init parameters:

Let’s see how construction works now:

Notice that we left out the size of Ezri’s coffee upon construction… Since this argument is missing, the size variable is assigned to the default “large”. Claire’s coffee size is specified, so the default “large” is ignored.