Python OOP (Object-Oriented Programming)
Object-Oriented Programming Concepts
Object-Oriented Programming (OOP) organizes code around objects rather than functions alone. Python supports OOP with four main principles:
- **Encapsulation**: Bundle data and methods that work on that data within a class
- **Abstraction**: Hide implementation details, exposing only essential behavior
- **Inheritance**: Build new classes from existing ones, reusing functionality
- **Polymorphism**: Provide a common interface for different types
Example
# Basic OOP example in Python
class Car:
# Class attribute
wheels = 4
# Constructor
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
self._mileage = 0 # Conventionally 'protected'
# Instance method
def drive(self, miles):
self._mileage += miles
return f"Driven {miles} miles. Total mileage: {self._mileage}"
# String representation
def __str__(self):
return f"{self.year} {self.brand} {self.model}"
# Creating objects
car1 = Car("Toyota", "Camry", 2022)
car2 = Car("Honda", "Civic", 2023)
print(car1)
print(car2)
print(car1.drive(150))
print(f"All cars have {Car.wheels} wheels")
Output
2022 Toyota Camry 2023 Honda Civic Driven 150 miles. Total mileage: 150 All cars have 4 wheels
Benefits of OOP
- Modularity: Classes and objects can be developed independently
- Reusability: Code can be reused across projects
- Scalability: Easy to extend and maintain large programs
- Security: Encapsulation restricts unintended data access
- Flexibility: Polymorphism supports adaptable, generalized code
OOP Principles in Practice
Python implements OOP using classes and objects. Since everything in Python is an object, classes serve as blueprints for object creation.
Example
# Demonstrating OOP principles
class BankAccount:
# Class variable
bank_name = "Python Bank"
def __init__(self, account_holder, balance=0):
self.account_holder = account_holder
self.__balance = balance # Name-mangled 'private' attribute
# Public method
def deposit(self, amount):
if amount > 0:
self.__balance += amount
return f"Deposited ${amount}. New balance: ${self.__balance}"
return "Invalid deposit amount"
def get_balance(self):
return f"Balance: ${self.__balance}"
# Class method
@classmethod
def change_bank_name(cls, new_name):
cls.bank_name = new_name
return f"Bank name changed to {new_name}"
# Using the class
account1 = BankAccount("Alice", 1000)
print(account1.deposit(500))
print(account1.get_balance())
print(BankAccount.change_bank_name("Advanced Python Bank"))
print(f"Bank name: {BankAccount.bank_name}")
Output
Deposited $500. New balance: $1500 Balance: $1500 Bank name changed to Advanced Python Bank Bank name: Advanced Python Bank