Skip to content

Latest commit

 

History

History
313 lines (225 loc) · 7.93 KB

File metadata and controls

313 lines (225 loc) · 7.93 KB

Comprehensive OOP Concepts and Python Applications

Slide 1: Introduction to Object-Oriented Programming (OOP)

Object-Oriented Programming is a programming paradigm that organizes code into objects, which are instances of classes. OOP focuses on the concept of objects that contain data and code, emphasizing the relationships between objects to design and structure programs.

class Car:
    def __init__(self, make, model):
        self.make = make
        self.model = model

    def display_info(self):
        return f"{self.make} {self.model}"

my_car = Car("Toyota", "Corolla")
print(my_car.display_info())

Slide 2: Encapsulation

Encapsulation is the bundling of data and the methods that operate on that data within a single unit (class). It restricts direct access to some of an object's components, which is a means of preventing accidental interference and misuse of the methods and data.

class BankAccount:
    def __init__(self):
        self.__balance = 0

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

    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount

    def get_balance(self):
        return self.__balance

account = BankAccount()
account.deposit(1000)
print(account.get_balance())

Slide 3: Polymorphism - Method Overriding

Polymorphism allows objects of different classes to be treated as objects of a common base class. Method overriding is a form of polymorphism where a subclass provides a specific implementation of a method that is already defined in its superclass.

class Animal:
    def speak(self):
        pass

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

class Cat(Animal):
    def speak(self):
        return "Meow!"

def animal_sound(animal):
    return animal.speak()

dog = Dog()
cat = Cat()
print(animal_sound(dog))
print(animal_sound(cat))

Slide 4: Polymorphism - Method Overloading

Python doesn't support method overloading by default, but we can simulate it using default arguments or variable-length arguments.

class Calculator:
    def add(self, *args):
        return sum(args)

calc = Calculator()
print(calc.add(2, 3))
print(calc.add(2, 3, 4))
print(calc.add(2, 3, 4, 5))

Slide 5: Composition

Composition is a design principle that states that classes should achieve polymorphic behavior and code reuse by their composition rather than inheritance from a base or parent class.

class Engine:
    def start(self):
        return "Engine started"

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

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

my_car = Car()
print(my_car.start())

Slide 6: Abstraction

Abstraction is the process of hiding the internal details and showing only the functionality. In Python, we can achieve abstraction using abstract base classes.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Square(Shape):
    def __init__(self, side):
        self.side = side

    def area(self):
        return self.side ** 2

square = Square(5)
print(square.area())

Slide 7: Aggregation

Aggregation is a special form of association where objects have a separate lifecycle but share ownership. It represents a "has-a" relationship between objects.

class Department:
    def __init__(self, name):
        self.name = name

class Employee:
    def __init__(self, name, department):
        self.name = name
        self.department = department

dep = Department("IT")
emp1 = Employee("Alice", dep)
emp2 = Employee("Bob", dep)

print(f"{emp1.name} works in {emp1.department.name}")
print(f"{emp2.name} works in {emp2.department.name}")

Slide 8: Association

Association represents a relationship between two or more objects where all objects have their own lifecycle and there is no owner. It can be one-to-one, one-to-many, or many-to-many.

class Student:
    def __init__(self, name):
        self.name = name
        self.courses = []

    def enroll(self, course):
        self.courses.append(course)
        course.add_student(self)

class Course:
    def __init__(self, name):
        self.name = name
        self.students = []

    def add_student(self, student):
        self.students.append(student)

student1 = Student("Alice")
course1 = Course("Python Programming")
student1.enroll(course1)

print(f"{student1.name} is enrolled in {student1.courses[0].name}")
print(f"{course1.name} has {course1.students[0].name} as a student")

Slide 9: Inheritance

Inheritance is a mechanism where a class can derive properties and characteristics from another class. It supports the concept of hierarchical classification and code reuse.

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return f"{self.name} says Woof!"

class Cat(Animal):
    def speak(self):
        return f"{self.name} says Meow!"

dog = Dog("Buddy")
cat = Cat("Whiskers")

print(dog.speak())
print(cat.speak())

Slide 10: Multiple Inheritance

Python supports multiple inheritance, allowing a class to inherit from multiple parent classes. This can lead to powerful combinations of behaviors but should be used carefully to avoid complexity.

class Flyer:
    def fly(self):
        return "I can fly!"

class Swimmer:
    def swim(self):
        return "I can swim!"

class Duck(Flyer, Swimmer):
    pass

duck = Duck()
print(duck.fly())
print(duck.swim())

Slide 11: Method Resolution Order (MRO)

When using multiple inheritance, Python uses the C3 Linearization algorithm to determine the order in which base classes are searched when looking for a method. This is known as the Method Resolution Order (MRO).

class A:
    def method(self):
        return "A"

class B(A):
    def method(self):
        return "B"

class C(A):
    def method(self):
        return "C"

class D(B, C):
    pass

d = D()
print(d.method())
print(D.mro())

Slide 12: Property Decorators

Property decorators provide a way to customize access to class attributes, allowing you to define methods that can be accessed like attributes.

class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius

    @property
    def celsius(self):
        return self._celsius

    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("Temperature below absolute zero is not possible")
        self._celsius = value

    @property
    def fahrenheit(self):
        return (self.celsius * 9/5) + 32

temp = Temperature(25)
print(f"Celsius: {temp.celsius}")
print(f"Fahrenheit: {temp.fahrenheit}")

temp.celsius = 30
print(f"New Celsius: {temp.celsius}")
print(f"New Fahrenheit: {temp.fahrenheit}")

Slide 13: Static and Class Methods

Static methods and class methods are special methods that can be called on a class without creating an instance of the class. They serve different purposes and have different behaviors.

class MathOperations:
    @staticmethod
    def add(x, y):
        return x + y

    @classmethod
    def multiply(cls, x, y):
        return cls.add(x, 0) * y

print(MathOperations.add(5, 3))
print(MathOperations.multiply(4, 2))

Slide 14: Additional Resources

For further exploration of Object-Oriented Programming concepts and their implementation in Python, consider the following resources:

  1. "Object-Oriented Programming in Python: A Comprehensive Study" by Bhargavi et al. (2023) ArXiv URL: https://arxiv.org/abs/2308.15827
  2. "Python Design Patterns" by Chetan Giridhar (Book)
  3. "Fluent Python" by Luciano Ramalho (Book)
  4. Python's official documentation on classes: https://docs.python.org/3/tutorial/classes.html

These resources provide in-depth explanations and advanced techniques for mastering OOP in Python.