Skip to content

Encapsulation and Polymorphism

In this section, you will learn two key concepts of object-oriented programming: encapsulation and polymorphism. Both help you write safer, more flexible, and reusable code.


Encapsulation consists of hiding the internal details of an object and exposing only what is necessary. This protects the object’s internal state and controls how it is accessed or modified.

  • “Private” attributes and methods are named with an underscore (_attribute or __attribute).
  • Methods called getters and setters are used to access or modify attributes if necessary.
Encapsulation with private attributes
class BankAccount:
def __init__(self, balance):
self.__balance = balance # private attribute
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def get_balance(self):
return self.__balance
account = BankAccount(100)
account.deposit(50)
print(account.get_balance()) # 150

In this example, the balance can only be modified by the defined methods, not directly from outside the class.


Polymorphism allows different classes to share the same method (name), but each has its own implementation. Thus, you can use objects of different classes interchangeably if they comply with the same interface.

Polymorphism in action
class Animal:
def speak(self):
print('Makes a sound')
class Dog(Animal):
def speak(self):
print('Woof!')
class Cat(Animal):
def speak(self):
print('Meow!')
animals = [Dog(), Cat()]
for animal in animals:
animal.speak()

Output:

Woof!
Meow!

Each object responds differently to the same speak method, depending on its class.


  • Encapsulation: protects internal data and controls access to it.
  • Polymorphism: allows the use of different objects uniformly if they share methods with the same name.
  • Both concepts make your code safer, more flexible, and easier to maintain.

Ready to practice? Try creating a class with private attributes and another class hierarchy that uses polymorphism.