Data StructuresDictionaries & SetsPython Basics

Python OOP Masterclass: Classes, Objects, and Inheritance Explained

As applications grow in scope, structuring code procedurally can lead to unmaintainable codebases. Object-Oriented Programming (OOP) provides a structured paradigm that bundles related data (attributes) and behaviors (methods) into reusable blueprints called classes.

This guide covers class definitions, object instantiation, the __init__ constructor, instance vs. class attributes, and extending functionality using inheritance.

Key Takeaways

  • A Class serves as a blueprint; an Object is a concrete instance of that blueprint.
  • The __init__ method initializes an object’s state upon instantiation.
  • self explicitly references the current instance accessing class attributes or methods.
  • Inheritance allows child classes to inherit and override methods from parent classes.

1. Defining Classes and Instantiating Objects

Define a class using the class keyword. The __init__ method acts as the constructor to assign initial state.

Python

class SystemNode:
    # Class attribute (shared across all instances)
    environment = "Production"

    def __init__(self, node_id, ip_address):
        # Instance attributes (unique to each object)
        self.node_id = node_id
        self.ip_address = ip_address
        self.is_active = False

    def activate(self):
        self.is_active = True
        print(f"Node {self.node_id} [{self.ip_address}] is online.")

# Instantiating objects
primary_node = SystemNode("Alpha-1", "192.168.1.10")
primary_node.activate()  # Output: Node Alpha-1 [192.168.1.10] is online.

2. Object Inheritance and super()

Inheritance enables a sub-class (child) to inherit all attributes and methods from a base-class (parent), promoting code reuse without duplication.

Python

# Base Parent Class
class DatabaseConnection:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def connect(self):
        print(f"Connecting to {self.host}:{self.port}...")

# Derived Child Class
class PostgresConnection(DatabaseConnection):
    def __init__(self, host, port, db_name):
        # Initialize parent attributes using super()
        super().__init__(host, port)
        self.db_name = db_name

    # Overriding parent method
    def connect(self):
        super().connect()
        print(f"Established connection to Postgres DB: '{self.db_name}'")

pg_client = PostgresConnection("localhost", 5432, "eduzik_analytics")
pg_client.connect()

3. Encapsulation: Public vs. Private Attributes

Python handles private attributes via naming conventions rather than strict access modifiers. Prefixing an attribute with double underscores __ triggers name mangling to prevent accidental direct access.

Python

class SecurityVault:
    def __init__(self, secret_key):
        self.public_id = "Vault_01"
        self.__secret_key = secret_key  # Private attribute

    def verify_key(self, input_key):
        return self.__secret_key == input_key

vault = SecurityVault("CYBER_SECURE_99")
print(vault.public_id)  # Output: Vault_01

# Direct access to __secret_key raises an AttributeError
# print(vault.__secret_key)

4. Class Methods vs. Static Methods

Method TypeDecoratorFirst ArgumentPrimary Purpose
Instance MethodNoneselfAccesses/modifies instance state
Class Method@classmethodclsAccesses/modifies class-level state or provides alternative constructors
Static Method@staticmethodNoneOperates as a utility function without accessing instance/class state

Conclusion

Mastering Python Object-Oriented Programming allows you to build modular, scalable, and maintainable software systems. Using encapsulation, class inheritance, and polymorphic methods ensures your codebase stays clean as architecture complexity expands.

Frequently Asked Questions

What is the purpose of self in Python classes?

self explicitly passes the instance object into the method. It allows methods to access and modify the specific instance’s attributes and other methods.

Can a Python child class inherit from multiple parent classes?

Yes. Python supports Multiple Inheritance. When multiple parent classes share method names, Python resolves access order using the Method Resolution Order (MRO) algorithm.

What is the difference between __str__ and __repr__?

__str__ provides a readable, user-friendly string representation of an object, while __repr__ provides an unambiguous developer-focused representation primarily used for debugging.

Leave a Reply

Your email address will not be published. Required fields are marked *