Python
  • Intro.
  • Catalogue
  • Chapter 1: Introduction to Python
  • Chapter 2: Python Syntax and Fundamentals
    • Chapter: Variables and Data Types in Python
  • Chapter 3: Control Flow
  • Chapter 4: Functions
  • Chapter 5: Data Structures
  • Chapter 6: Object-Oriented Programming (OOP)
  • Chapter 7: Modules and Packages
  • Chapter 8: File Handling
  • Chapter 9: Error and Exception Handling
  • Chapter 10: Working with Databases
  • Chapter 11: Iterators and Generators
  • Chapter 12: Decorators and Context Managers
  • Chapter 13: Concurrency and Parallelism
  • Chapter 14: Testing and Debugging
  • Chapter 15: Web Development with Python
  • Chapter 16: Data Science and Machine Learning with Python
  • Chapter 17: Working with APIs
  • Chapter 18: Automation with Python
  • Chapter 19: Python and Cloud/DevOps
  • Chapter 20: Python and IoT
  • Appendices
Powered by GitBook
On this page

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

  1. Classes and Objects:

    • A class is a blueprint for creating objects.

    • An object is an instance of a class.

  2. Attributes and Methods:

    • Attributes represent the data of an object.

    • Methods are functions defined inside a class that operate on objects.

  3. Encapsulation:

    • Bundling data and methods together.

    • Restricting access to certain parts of an object using access modifiers.

  4. Inheritance:

    • Mechanism for creating a new class (child) from an existing class (parent).

  5. Polymorphism:

    • Ability for methods to perform different actions based on the object that calls them.

  6. 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 using self.

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.

PreviousChapter 5: Data StructuresNextChapter 7: Modules and Packages

Last updated 5 months ago