Python Object-Oriented Programming (OOP)
Object-Oriented Programming (OOP) is a powerful programming paradigm that uses "objects" to design software. Objects bundle data (attributes) and functions that operate on data (methods) together. Python has been an object-oriented language from the beginning.
Classes and Objects
- Class: Is a blueprint or template for creating objects. It defines the attributes and methods that an object will have.
- Object: Is an instance of a class. You can create many objects from a single class; each object has the attributes and methods defined by the class but can have its own independent data.
Think of a class as a "car" blueprint, while an object is each specific car manufactured according to that blueprint (like your car, my car).
Defining a Class
Use the class keyword to define a class.
class Dog:
"""A simple class representing a puppy."""
# The __init__ method is a special method for initializing objects
# When you create a new Dog instance, Python automatically calls it
def __init__(self, name, age):
"""Initialize the name and age attributes."""
self.name = name # Attribute
self.age = age # Attribute
# Method
def sit(self):
"""Simulate the puppy sitting."""
print(f"{self.name} is now sitting.")
def roll_over(self):
"""Simulate the puppy rolling over."""
print(f"{self.name} rolled over!")The self Parameter
You may have noticed the self parameter as the first parameter in all methods. It's a reference to the instance itself, allowing the instance to access its own attributes and methods. When calling a method, you do not need to pass arguments for self; Python handles this automatically.
Creating and Using Objects
Creating an instance of a class (i.e., instantiation) is just like calling a function.
# Create an instance named my_dog from the Dog class
my_dog = Dog("Willie", 6)
# Access attributes
print(f"My dog's name is {my_dog.name}.")
print(f"My dog is {my_dog.age} years old.")
# Call methods
my_dog.sit()
my_dog.roll_over()Inheritance
Inheritance is a core concept in OOP that allows us to create a new class (child class) that inherits all attributes and methods from an existing class (parent class). Child classes can override methods from the parent class or add their own new methods.
This enables code reuse.
# Create a parent class
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
print("Some generic animal sound")
# Create a child class Cat that inherits from Animal
class Cat(Animal):
def __init__(self, name, color):
# super() function is used to call parent class methods
super().__init__(name) # Call the parent class's __init__ method
self.color = color
# Override the parent class's speak method
def speak(self):
print("Meow!")
# Add your own new method
def purr(self):
print(f"{self.name} is purring.")
# Create instance
my_cat = Cat("Mitty", "white")
my_cat.speak() # Calls the method overridden in the Cat class -> Meow!
my_cat.purr() # Calls Cat's own method -> Mitty is purring.Encapsulation
Encapsulation refers to bundling data (attributes) and code that operates on data (methods) into a single unit (class). In Python, we typically use naming conventions to indicate attribute visibility:
name: Public attribute, can be freely accessed from outside the class._name: "Protected" attribute, by convention should only be used within the class and its subclasses.__name: "Private" attribute, Python performs name mangling on it, making it difficult to access directly from outside, thus achieving stronger encapsulation.
Encapsulation helps hide an object's internal state while exposing only necessary interfaces, thereby improving code security and maintainability.