OOP & Classes

Object-oriented programming (OOP) allows us to structure and organize code by representing real-world objects or concepts as classes, which encapsulate data and behaviour.

This offers several advantages including code reusability, modularity, and abstraction. The latter allows you to hide implementation details and only expose relevant interfaces, making code easier to read and maintain.

Blueprints

All cars have things that make them a Car. Although the details might be different, every type of car has the same basics — it's based off the same blueprint, with the same properties and actions.

  • Property: A type (could be hatchback or sedan).

  • Property: A color (could be red, black, blue, or silver).

  • Property: Seats (could be between 2 and 7).

  • Action: Can drive.

  • Action: Can park.

  • When we make a car, we can vary the values of these properties. Some cars have economy engines, some have performance engines. Some have four doors, others have two. However, they are all types of Cars.

Defining Classes

Class definitions are similar to function definitions, but instead of def, we use class.

Let's declare a class for Dog:

class Dog:
    # We'll define the class here.
    # Our dog will have two attributes: name and age.
    pass

Pro tip: While objects are named in snake_case, classes are conventionally named in TitleCase.

The __init__ Method

What first? Every class starts with an __init__ method. It's:

  • Where we define the class' variables.

  • Short for "initialize." This is the constructor function.

class Dog:
    def __init__(self, name, age):
        self.name = name  # All dogs have a name.
        self.age = age  # All dogs have an age.

Note: self means "each individual object made from this class." Not every "dog" has the same name!

  • The first argument passed to the __init__ function, self, is required when defining methods for classes. The self argument is a reference to a future instantiation of the class. In other words, self refers to each individual dog.

  • This lets each object made from a class keep references to its own data and function members. Not every "dog" has the same attributes, so we want individual dogs to maintain their own attributes.

Adding a bark_hello() Method

class Dog:
    def __init__(self, name, age):
        self.name = name  # All dogs have a name.
        self.age = age  # All dogs have an age.

    # All dogs have a bark_hello function.
    def bark_hello(self):
        print("Woof! I am called", self.name, "; I am", self.age, "human-years old.")

Instantiating Objects From Classes

Now we have a Dog blueprint!

Each dog object we make from this blueprint:

  • Has a name.

  • Has an age.

  • Can bark.

How Do We Make a Dog Object?

We call our class name like we call a function — passing in arguments, which go to the __init__ method of the class.

Add this under your class (non-indented!):

# Declare the objects.
tonto = Dog("Tonto", 5)
scout = Dog("Scout", 7)
sailor = Dog("Sailor", 3)

# Test them out!
tonto.bark_hello()
print("This dog's name is", tonto.name)
print("This dog's age is", tonto.age)
scout.bark_hello()
sailor.bark_hello()

Last updated