Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Advanced OOP Concepts in Python

Inheritance

Inheritance allows a class (child class) to inherit attributes and methods from another class (parent class).

Important: Inheritance promotes code reuse and establishes a relationship between classes.
class Parent:
    def greet(self):
        print("Hello from Parent!")

class Child(Parent):
    def greet_child(self):
        print("Hello from Child!")

child = Child()
child.greet()  # Output: Hello from Parent!

Polymorphism

Polymorphism allows methods to do different things based on the object it is acting upon.

Tip: Polymorphism can be achieved through method overriding and duck typing.
class Dog:
    def sound(self):
        return "Woof!"

class Cat:
    def sound(self):
        return "Meow!"

def animal_sound(animal):
    print(animal.sound())

dog = Dog()
cat = Cat()

animal_sound(dog)  # Output: Woof!
animal_sound(cat)  # Output: Meow!

Encapsulation

Encapsulation restricts access to certain attributes and methods, protecting object integrity.

Warning: Use encapsulation to prevent unintended interference with object states.
class BankAccount:
    def __init__(self, balance):
        self.__balance = balance  # Private attribute

    def deposit(self, amount):
        self.__balance += amount

    def get_balance(self):
        return self.__balance

account = BankAccount(100)
account.deposit(50)
print(account.get_balance())  # Output: 150

Abstraction

Abstraction hides the complex reality while exposing only the necessary parts. It can be implemented using abstract classes and interfaces.

Tip: Use abstract classes to define methods that must be created in any child class.
from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod
    def sound(self):
        pass

class Dog(Animal):
    def sound(self):
        return "Woof!"

dog = Dog()
print(dog.sound())  # Output: Woof!

Composition

Composition is a design principle where a class is composed of one or more objects from other classes, establishing a "has-a" relationship.

Tip: Composition is preferred over inheritance for better flexibility and maintainability.
class Engine:
    def start(self):
        print("Engine starting...")

class Car:
    def __init__(self):
        self.engine = Engine()  # Car has an engine

    def start(self):
        self.engine.start()

my_car = Car()
my_car.start()  # Output: Engine starting...

Metaclasses

Metaclasses are classes of classes that define how a class behaves. They can be used to customize class creation.

Warning: Metaclasses can add complexity and should be used judiciously.
class Meta(type):
    def __new__(cls, name, bases, attrs):
        attrs['id'] = 1  # Adding an attribute
        return super().__new__(cls, name, bases, attrs)

class MyClass(metaclass=Meta):
    pass

print(MyClass.id)  # Output: 1

FAQ

What is the difference between encapsulation and abstraction?

Encapsulation is about restricting access to certain components, while abstraction is about hiding complexity and exposing only the essential parts.

When should I use inheritance vs. composition?

Use inheritance when there is a clear hierarchical relationship and composition when you want to build complex types by combining simpler types.