No history yet

Introduction to OOP

A New Way to Organize Code

So far, you've likely written code using functions to perform tasks. This is great for small programs, but as your projects grow, just having a long list of functions can get complicated. It's hard to keep track of which functions work with which pieces of data.

Object-Oriented Programming, or OOP, offers a solution. It's a way of thinking about and structuring your code that groups related data and the functions that operate on that data into neat, reusable bundles. The core idea is to model real-world things.

Think about a user account on a website. It has data, like a username and an email address. It also has actions it can perform, like changing a password or logging out. OOP lets us bundle the user's data (attributes) and actions (methods) together into a single unit called an object.

In OOP, we create objects that contain both data and functionality.

Blueprints and Buildings

To create these objects, we first need a blueprint. In Python, this blueprint is called a class. A class defines the structure and behavior for a type of object, but it isn't an object itself. It's like the architectural plan for a house; it details what the house will have, but you can't live in the plan.

An object created from a class is called an instance. Using our house analogy, an instance is the actual, physical house built from the blueprint. You can build many houses (instances) from the same blueprint (class), and each one is a separate entity.

Lesson image

Let's define a simple class for a dog. By convention, class names in Python start with a capital letter.

class Dog:
    pass # The 'pass' keyword means we're not adding any details yet

This class doesn't do much, but it's a valid blueprint. Now, let's create two instances (two separate dogs) from our Dog class.

# Create two instances of the Dog class
fido = Dog()
spot = Dog()

We now have two distinct Dog objects, fido and spot. They were made from the same blueprint, but they are independent of each other, just like two houses built from the same plan.

Describing and Doing

Our Dog class is pretty boring. Let's give it some characteristics (data) and behaviors (actions). In OOP, these are called attributes and methods.

Attributes are variables that belong to an object. They store the state or data of that specific instance. For a dog, this could be its name and age.

Methods are functions that belong to an object. They define what the object can do. A dog can bark, for instance.

To set up the initial attributes for an object, we use a special method called __init__. This method is run automatically whenever a new instance of the class is created. It's often called a constructor.

class Dog:
    # The constructor method
    def __init__(self, name, age):
        # Attributes
        self.name = name
        self.age = age

    # A method
    def bark(self):
        return f"{self.name} says woof!"

You'll notice the self parameter in both __init__ and bark. The self keyword is a reference to the current instance of the class. It's how the object can access its own attributes and methods. When we write self.name = name, we're telling Python, "Take the name value that was passed in and assign it to this specific instance's name attribute."

Now, let's create a dog with these new details.

# Create an instance, passing arguments to __init__
my_dog = Dog("Fido", 5)

# Access the instance's attributes
print(my_dog.name)  # Output: Fido
print(my_dog.age)     # Output: 5

# Call the instance's method
print(my_dog.bark())  # Output: Fido says woof!

Notice that when we call my_dog.bark(), we don't pass anything in for the self parameter. Python does that for us automatically behind the scenes. It passes the my_dog object itself as the first argument to the method.

This principle of bundling data (attributes) and the methods that operate on that data into a single object is called encapsulation. It helps keep your code organized and prevents data from being changed in unexpected ways.

Let's try one more example. We can create a Car class.

class Car:
    def __init__(self, make, model):
        self.make = make
        self.model = model
        self.speed = 0 # All cars start at 0 speed

    def accelerate(self):
        self.speed += 10
        return f"The {self.make} {self.model} is now going {self.speed} mph."

    def brake(self):
        self.speed -= 10
        if self.speed < 0:
            self.speed = 0
        return f"The {self.make} {self.model} slowed down to {self.speed} mph."

Now you can create a Car instance and interact with it.

my_car = Car("Toyota", "Camry")
print(my_car.accelerate())
print(my_car.accelerate())
print(my_car.brake())

Each car object would have its own make, model, and current speed, all neatly packaged together. This is the power of OOP. It allows you to create organized, predictable, and reusable code by modeling the world around you.

Quiz Questions 1/5

In Object-Oriented Programming, what is the relationship between a class and an object?

Quiz Questions 2/5

What is the primary purpose of the special __init__ method in a Python class?

You've just taken your first step into object-oriented programming. By understanding classes, objects, attributes, and methods, you have a powerful new tool for building more complex and well-structured applications.