Chapter 6: Object-Oriented Programming (OOP)
Object-Oriented Programming (OOP) is a programming paradigm that organizes code into objects. Objects encapsulate data (attributes) and behavior (methods), making it easier to manage and scale programs.
Key Concepts of OOP
Classes and Objects:
A class is a blueprint for creating objects.
An object is an instance of a class.
Attributes and Methods:
Attributes represent the data of an object.
Methods are functions defined inside a class that operate on objects.
Encapsulation:
Bundling data and methods together.
Restricting access to certain parts of an object using access modifiers.
Inheritance:
Mechanism for creating a new class (child) from an existing class (parent).
Polymorphism:
Ability for methods to perform different actions based on the object that calls them.
Abstraction:
Hiding complex implementation details and showing only the essential features.
Defining and Creating Classes
Syntax:
class ClassName:
def __init__(self, parameters):
self.attribute = value # Initializing attributes
def method(self):
# Method logic
Example:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print(f"Hello, my name is {self.name} and I am {self.age} years old.")
# Creating objects
person1 = Person("Alice", 25)
person1.greet() # Output: Hello, my name is Alice and I am 25 years old.
Attributes and Methods
Instance Attributes:
Specific to an object.
Defined in the
__init__
method usingself
.
Class Attributes:
Shared by all instances of the class.
Defined directly within the class.
class Circle:
pi = 3.14 # Class attribute
def __init__(self, radius):
self.radius = radius # Instance attribute
def area(self):
return Circle.pi * self.radius ** 2
circle = Circle(5)
print(circle.area()) # Output: 78.5
Encapsulation
Encapsulation allows control over access to attributes and methods.
Access Modifiers:
Public: Attributes and methods accessible anywhere (default).
Protected: Indicated by a single underscore
_
. Should be accessed only within the class and its subclasses.Private: Indicated by a double underscore
__
. Accessible only within the class.
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(1000)
account.deposit(500)
print(account.get_balance()) # Output: 1500
Inheritance
Inheritance enables a class to acquire attributes and methods from another class.
Syntax:
class ParentClass:
# Parent class definition
class ChildClass(ParentClass):
# Child class definition
Example:
class Animal:
def speak(self):
print("Animal makes a sound.")
class Dog(Animal):
def speak(self):
print("Dog barks.")
animal = Animal()
animal.speak() # Output: Animal makes a sound.
dog = Dog()
dog.speak() # Output: Dog barks.
Polymorphism
Polymorphism allows different classes to define methods with the same name but different behavior.
Example:
class Bird:
def move(self):
print("Bird flies.")
class Fish:
def move(self):
print("Fish swims.")
animals = [Bird(), Fish()]
for animal in animals:
animal.move()
# Output:
# Bird flies.
# Fish swims.
Abstraction
Abstraction hides the implementation details and shows only the functionality.
Example with Abstract Base Class:
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
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
rectangle = Rectangle(5, 10)
print(rectangle.area()) # Output: 50
Exercises
Exercise 1:
Create a class Car
with attributes make
, model
, and year
. Include a method to display the car’s details.
Solution:
class Car:
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
def display_details(self):
print(f"Car: {self.year} {self.make} {self.model}")
car = Car("Toyota", "Corolla", 2022)
car.display_details() # Output: Car: 2022 Toyota Corolla
Exercise 2:
Create a base class Employee
and a subclass Manager
. The Manager
class should have an additional attribute department
and a method to display all details.
Solution:
class Employee:
def __init__(self, name, id):
self.name = name
self.id = id
def display(self):
print(f"Employee Name: {self.name}, ID: {self.id}")
class Manager(Employee):
def __init__(self, name, id, department):
super().__init__(name, id)
self.department = department
def display(self):
super().display()
print(f"Department: {self.department}")
manager = Manager("Alice", 101, "HR")
manager.display()
# Output:
# Employee Name: Alice, ID: 101
# Department: HR
Exercise 3:
Create an abstract class Appliance
with a method turn_on
. Implement two subclasses WashingMachine
and Refrigerator
that provide specific implementations for turn_on
.
Solution:
from abc import ABC, abstractmethod
class Appliance(ABC):
@abstractmethod
def turn_on(self):
pass
class WashingMachine(Appliance):
def turn_on(self):
print("Washing machine is now ON.")
class Refrigerator(Appliance):
def turn_on(self):
print("Refrigerator is now ON.")
wm = WashingMachine()
wm.turn_on() # Output: Washing machine is now ON.
fridge = Refrigerator()
fridge.turn_on() # Output: Refrigerator is now ON.
In the next chapter, we will explore modules and packages, understanding how to organize and reuse code effectively in Python.
Last updated