python

examples

examples.py🐍
"""
09 - OOP: Examples
Run this file to see OOP concepts in action!
"""

print("=" * 60)
print("OBJECT-ORIENTED PROGRAMMING - EXAMPLES")
print("=" * 60)

# =============================================================================
# 1. BASIC CLASS AND OBJECTS
# =============================================================================
print("\n--- 1. Basic Class and Objects ---\n")

class Dog:
    # Class attribute
    species = "Canis familiaris"
    
    def __init__(self, name, age):
        # Instance attributes
        self.name = name
        self.age = age
    
    def bark(self):
        return f"{self.name} says Woof!"
    
    def description(self):
        return f"{self.name} is {self.age} years old"

# Create objects
buddy = Dog("Buddy", 5)
max_dog = Dog("Max", 3)

print(f"buddy.name: {buddy.name}")
print(f"buddy.species: {buddy.species}")
print(f"buddy.bark(): {buddy.bark()}")
print(f"max_dog.description(): {max_dog.description()}")

# =============================================================================
# 2. INSTANCE VS CLASS VARIABLES
# =============================================================================
print("\n--- 2. Instance vs Class Variables ---\n")

class Employee:
    company = "TechCorp"
    employee_count = 0
    
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        Employee.employee_count += 1

emp1 = Employee("Alice", 50000)
emp2 = Employee("Bob", 60000)

print(f"Employee count: {Employee.employee_count}")
print(f"emp1.company: {emp1.company}")
print(f"emp2.company: {emp2.company}")

# Change class variable
Employee.company = "MegaCorp"
print(f"After change - emp1.company: {emp1.company}")

# =============================================================================
# 3. TYPES OF METHODS
# =============================================================================
print("\n--- 3. Types of Methods ---\n")

class Circle:
    pi = 3.14159
    
    def __init__(self, radius):
        self.radius = radius
    
    # Instance method
    def area(self):
        return Circle.pi * self.radius ** 2
    
    # Class method
    @classmethod
    def from_diameter(cls, diameter):
        return cls(diameter / 2)
    
    @classmethod
    def update_pi(cls, value):
        cls.pi = value
    
    # Static method
    @staticmethod
    def is_valid_radius(radius):
        return radius > 0

# Instance method
c1 = Circle(5)
print(f"Area of circle with radius 5: {c1.area():.2f}")

# Class method as factory
c2 = Circle.from_diameter(10)
print(f"Radius from diameter 10: {c2.radius}")

# Static method
print(f"Is 5 valid radius? {Circle.is_valid_radius(5)}")
print(f"Is -1 valid radius? {Circle.is_valid_radius(-1)}")

# =============================================================================
# 4. ENCAPSULATION
# =============================================================================
print("\n--- 4. Encapsulation ---\n")

class BankAccount:
    def __init__(self, owner, balance):
        self.owner = owner              # Public
        self._account_type = "savings"  # Protected
        self.__balance = balance        # Private
    
    def get_balance(self):
        return self.__balance
    
    def deposit(self, amount):
        if amount > 0:
            self.__balance += amount
            return True
        return False
    
    def withdraw(self, amount):
        if 0 < amount <= self.__balance:
            self.__balance -= amount
            return True
        return False

account = BankAccount("Alice", 1000)
print(f"Owner (public): {account.owner}")
print(f"Account type (protected): {account._account_type}")
print(f"Balance (via getter): {account.get_balance()}")

account.deposit(500)
print(f"After deposit 500: {account.get_balance()}")

# =============================================================================
# 5. PROPERTY DECORATOR
# =============================================================================
print("\n--- 5. Property Decorator ---\n")

class Temperature:
    def __init__(self, celsius=0):
        self._celsius = celsius
    
    @property
    def celsius(self):
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("Below absolute zero!")
        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 = 100
print(f"After setting to 100C: {temp.fahrenheit}F")

# =============================================================================
# 6. INHERITANCE
# =============================================================================
print("\n--- 6. Inheritance ---\n")

class Animal:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
    def speak(self):
        return "Some sound"
    
    def description(self):
        return f"{self.name} is {self.age} years old"

class Dog(Animal):
    def __init__(self, name, age, breed):
        super().__init__(name, age)
        self.breed = breed
    
    def speak(self):
        return f"{self.name} says Woof!"
    
    def fetch(self):
        return f"{self.name} is fetching!"

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

dog = Dog("Buddy", 5, "Golden Retriever")
cat = Cat("Whiskers", 3)

print(f"Dog: {dog.description()}")
print(f"Dog speak: {dog.speak()}")
print(f"Dog fetch: {dog.fetch()}")
print(f"Dog breed: {dog.breed}")
print(f"Cat speak: {cat.speak()}")

# =============================================================================
# 7. MULTIPLE INHERITANCE
# =============================================================================
print("\n--- 7. Multiple Inheritance ---\n")

class Flyable:
    def fly(self):
        return f"{self.name} is flying!"

class Swimmable:
    def swim(self):
        return f"{self.name} is swimming!"

class Duck(Animal, Flyable, Swimmable):
    def speak(self):
        return f"{self.name} says Quack!"

duck = Duck("Donald", 2)
print(f"Duck speak: {duck.speak()}")
print(f"Duck fly: {duck.fly()}")
print(f"Duck swim: {duck.swim()}")
print(f"MRO: {[c.__name__ for c in Duck.__mro__]}")

# =============================================================================
# 8. POLYMORPHISM
# =============================================================================
print("\n--- 8. Polymorphism ---\n")

class Shape:
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        return self.width * self.height

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius
    
    def area(self):
        return 3.14159 * self.radius ** 2

class Triangle(Shape):
    def __init__(self, base, height):
        self.base = base
        self.height = height
    
    def area(self):
        return 0.5 * self.base * self.height

# Polymorphism in action
shapes = [
    Rectangle(4, 5),
    Circle(3),
    Triangle(6, 4)
]

print("Areas of different shapes:")
for shape in shapes:
    print(f"  {type(shape).__name__}: {shape.area():.2f}")

# =============================================================================
# 9. ABSTRACT CLASSES
# =============================================================================
print("\n--- 9. Abstract Classes ---\n")

from abc import ABC, abstractmethod

class Vehicle(ABC):
    def __init__(self, brand):
        self.brand = brand
    
    @abstractmethod
    def start(self):
        pass
    
    @abstractmethod
    def stop(self):
        pass
    
    def description(self):
        return f"This is a {self.brand}"

class Car(Vehicle):
    def start(self):
        return f"{self.brand} car engine starting... Vroom!"
    
    def stop(self):
        return f"{self.brand} car engine stopping..."

class Bicycle(Vehicle):
    def start(self):
        return f"Pedaling the {self.brand} bicycle..."
    
    def stop(self):
        return f"Braking the {self.brand} bicycle..."

car = Car("Toyota")
bike = Bicycle("Trek")

print(car.description())
print(car.start())
print(bike.start())

# =============================================================================
# 10. MAGIC METHODS
# =============================================================================
print("\n--- 10. Magic Methods ---\n")

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return f"Vector({self.x}, {self.y})"
    
    def __repr__(self):
        return f"Vector({self.x!r}, {self.y!r})"
    
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __sub__(self, other):
        return Vector(self.x - other.x, self.y - other.y)
    
    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)
    
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y
    
    def __abs__(self):
        return (self.x**2 + self.y**2) ** 0.5
    
    def __bool__(self):
        return self.x != 0 or self.y != 0

v1 = Vector(3, 4)
v2 = Vector(1, 2)

print(f"v1: {v1}")
print(f"v2: {v2}")
print(f"v1 + v2: {v1 + v2}")
print(f"v1 - v2: {v1 - v2}")
print(f"v1 * 2: {v1 * 2}")
print(f"v1 == v2: {v1 == v2}")
print(f"abs(v1): {abs(v1)}")
print(f"bool(v1): {bool(v1)}")
print(f"bool(Vector(0, 0)): {bool(Vector(0, 0))}")

# =============================================================================
# 11. CALLABLE OBJECTS
# =============================================================================
print("\n--- 11. Callable Objects ---\n")

class Multiplier:
    def __init__(self, factor):
        self.factor = factor
    
    def __call__(self, value):
        return value * self.factor

double = Multiplier(2)
triple = Multiplier(3)

print(f"double(5): {double(5)}")
print(f"triple(5): {triple(5)}")

# =============================================================================
# 12. PRACTICAL EXAMPLE - LIBRARY SYSTEM
# =============================================================================
print("\n--- 12. Practical Example - Library ---\n")

class Book:
    def __init__(self, title, author, isbn):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.is_borrowed = False
    
    def __str__(self):
        status = "Available" if not self.is_borrowed else "Borrowed"
        return f'"{self.title}" by {self.author} [{status}]'

class Library:
    def __init__(self, name):
        self.name = name
        self.books = []
    
    def add_book(self, book):
        self.books.append(book)
        print(f"Added: {book.title}")
    
    def borrow_book(self, isbn):
        for book in self.books:
            if book.isbn == isbn and not book.is_borrowed:
                book.is_borrowed = True
                return f"Borrowed: {book.title}"
        return "Book not available"
    
    def return_book(self, isbn):
        for book in self.books:
            if book.isbn == isbn and book.is_borrowed:
                book.is_borrowed = False
                return f"Returned: {book.title}"
        return "Book not found"
    
    def list_available(self):
        available = [b for b in self.books if not b.is_borrowed]
        return available

# Create library and books
library = Library("City Library")

book1 = Book("Python Crash Course", "Eric Matthes", "123")
book2 = Book("Clean Code", "Robert Martin", "456")
book3 = Book("Design Patterns", "Gang of Four", "789")

library.add_book(book1)
library.add_book(book2)
library.add_book(book3)

print(f"\n{library.borrow_book('123')}")
print(f"\nAvailable books:")
for book in library.list_available():
    print(f"  {book}")

print(f"\n{library.return_book('123')}")

print("\n" + "=" * 60)
print("END OF EXAMPLES")
print("=" * 60)
Examples - Python Tutorial | DeepML