Skip to main content

Object-Oriented Programming in Python

 Object-Oriented Programming (OOP) in Python

Table of Contents

  1. Introduction to OOP
  2. Core Concepts of OOP
    • Classes and Objects
    • Attributes and Methods
    • Inheritance
    • Encapsulation
    • Polymorphism
  3. Implementing OOP in Python
    • Defining Classes
    • Creating Objects
    • Using Methods and Attributes
    • The __init__ Method
  4. Inheritance in Python
    • Single Inheritance
    • Multiple Inheritance
    • Method Resolution Order (MRO)
  5. Encapsulation in Python
    • Private and Protected Members
    • Getter and Setter Methods
  6. Polymorphism in Python
    • Method Overriding
    • Operator Overloading
  7. Abstract Classes and Interfaces
  8. Conclusion
  9. Further Reading

1. Introduction to OOP

Object-Oriented Programming (OOP) is a programming paradigm based on the concept of "objects," which can contain data and code: data in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods). Python, being a multi-paradigm language, supports OOP, allowing for encapsulation, inheritance, and polymorphism.

2. Core Concepts of OOP

Classes and Objects

  • Class: A blueprint for creating objects. It defines a set of attributes and methods that the created objects (instances) will have.
  • Object: An instance of a class. Each object can have different values for its attributes but will share the methods defined in the class.

Attributes and Methods

  • Attributes: Variables that belong to the class. They define the properties of the class.
  • Methods: Functions that belong to the class. They define the behavior of the objects created from the class.

Inheritance

Inheritance allows one class (the child or derived class) to inherit the attributes and methods of another class (the parent or base class). This promotes code reuse and establishes a natural hierarchy.

Encapsulation

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

Polymorphism

Polymorphism allows methods to do different things based on the object it is acting upon. This is often achieved through method overriding, where a derived class provides a specific implementation of a method already defined in its base class.

3. Implementing OOP in Python

Defining Classes

In Python, classes are defined using the class keyword.

python
class Dog
def bark(self): 
return "Woof!"

Creating Objects

Objects are created by calling the class as if it were a function.

python
my_dog = Dog() 
print(my_dog.bark()) 
# Output: Woof!

Using Methods and Attributes

You can add attributes to your class and access them through objects.

python
class Dog:
    def __init__(self, name): 
      self.name = name 
      def bark(self): 
      return f"{self.name} says Woof!" 
 my_dog = Dog("Buddy"
print(my_dog.bark())
# Output: Buddy says Woof!

The __init__ Method

The __init__ method is a special method in Python that initializes newly created objects. It’s often called the constructor.

python
class Cat
 d   def __init__(self, name, age): 
      self.name = name self.age = age
   my_cat = Cat("Whiskers", 3
print(f"{my_cat.name} is {my_cat.age} years old."
# Output: Whiskers is 3 years old.

4. Inheritance in Python

Single Inheritance

In single inheritance, a class inherits from one base class.

python
class Animal:
 def speak(self):
   return "Animal sound"
    class Dog(Animal):
    def bark(self): 
return "Woof!" 
 my_dog = Dog() 
print(my_dog.speak()) 
# Output: Animal sound

Multiple Inheritance

A class can also inherit from multiple base classes.

python
class Flyer
  def fly(self):
   return "Flying" 
  class Bird(Animal, Flyer): 
     def chirp(self): 
     return "Chirp!" my_bird = Bird() 
  print(my_bird.speak()) 
# Output: Animal sound print(my_bird.fly()) # Output: Flying

Method Resolution Order (MRO)

Python uses the C3 linearization algorithm to determine the order in which classes are resolved. You can view the MRO for a class using the __mro__ attribute or the mro() method.

python
print(Bird.__mro__)

5. Encapsulation in Python

Encapsulation involves restricting access to certain details of an object and is often implemented using private and protected members.

Private and Protected Members

In Python, attributes can be made private by prefixing them with two underscores __ or protected with a single underscore _.

python
class Car:
    def __init__(self, make):  
     self.__make = make # Private attribute 
def get_make(self): 
return self.__make my_car = Car("Toyota"
print(my_car.get_make()) 
# Output: Toyota # print(my_car.__make) # Raises AttributeError

Getter and Setter Methods

Getter and setter methods allow controlled access to private attributes.

python
class BankAccount
def __init__(self, balance):
   self.__balance = balance 
      def get_balance(self): 
      return self.__balance 
def set_balance(self, amount): 
if amount >= 0:
       self.__balance = amount 
else
    print("Invalid balance") account = 
BankAccount(100
print(account.get_balance()) 
# Output: 100 
account.set_balance(200
print(account.get_balance()) 
# Output: 200

6. Polymorphism in Python

Method Overriding

Method overriding allows a derived class to provide a specific implementation of a method that is already defined in its base class.

python
class Animal:
def sound(self): 
   return "Some sound" 
class Dog(Animal): 
   def sound(self):
return "Bark" my_animal = Dog() 
print(my_animal.sound()) 
# Output: Bark

Operator Overloading

Python allows you to define how operators behave with your objects.

python
class Point
  def __init__(self, x, y): 
 self.x = x 
 self.y = y 
def __add__(self, other): 
    return Point(self.x + other.x, self.y + other.y) 
 p1 = Point(1, 2
p2 = Point(3, 4
p3 = p1 + p2 
print(p3.x, p3.y) 
# Output: 4 6

7. Abstract Classes and Interfaces

Abstract classes cannot be instantiated and are meant to be subclassed. They can define abstract methods that must be implemented by derived classes.

python
from abc import ABC, abstractmethod 
class Shape(ABC): 
   @abstractmethod 
    def area(self): 
pass 
class Circle(Shape): 
def __init__(self, radius): 
 self.radius = radius 
def area(self): 
return 3.14 * (self.radius ** 2
 my_circle = Circle(5
print(my_circle.area()) 
# Output: 78.5

8. Conclusion

Object-Oriented Programming in Python provides a powerful way to structure code using classes and objects, promoting code reuse and modularity. Understanding concepts such as encapsulation, inheritance, and polymorphism is essential for effective programming in Python