0% found this document useful (0 votes)
3 views11 pages

Understanding Encapsulation in OOP

Encapsulation is a fundamental concept in Object-Oriented Programming that combines data and methods within a class while restricting direct access to internal data. It serves to protect sensitive information, control data modification through getter and setter methods, and maintain code integrity. Python implements encapsulation using naming conventions for access modifiers and provides the @property decorator for cleaner getter and setter definitions.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views11 pages

Understanding Encapsulation in OOP

Encapsulation is a fundamental concept in Object-Oriented Programming that combines data and methods within a class while restricting direct access to internal data. It serves to protect sensitive information, control data modification through getter and setter methods, and maintain code integrity. Python implements encapsulation using naming conventions for access modifiers and provides the @property decorator for cleaner getter and setter definitions.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Encapsulation is one of the four main pillars of Object-Oriented

Programming (OOP) (along with inheritance, polymorphism, and


abstraction).
It means binding data (variables) and methods (functions) that
operate on that data within a single unit (class) and restricting
direct access to some of the object’s internal data.

In simple terms:

Encapsulation = Data Hiding + Controlled Access

💡 Purpose of Encapsulation

 Protect sensitive data from unauthorized access.

 Control how data is modified (via getter and setter methods).

 Keep the internal representation of an object hidden from the


outside world.

 Maintain code integrity and security.

🔹 Example 1: Basic Encapsulation

class Student:

def __init__(self, name, marks):

[Link] = name # public variable

self.__marks = marks # private variable (encapsulated)

def show(self):

print(f"Name: {[Link]}, Marks: {self.__marks}")

# getter method

def get_marks(self):

return self.__marks

# setter method

def set_marks(self, marks):


if 0 <= marks <= 100:

self.__marks = marks

else:

print("Invalid marks!")

obj = Student("Abhay", 85)

[Link]()

obj.set_marks(92) # controlled access through setter

print(obj.get_marks()) # controlled access through getter

📘 Output:

Name: Abhay, Marks: 85

92

🔍 What’s Happening Internally

 __marks is a private variable (name-mangled to _Student__marks).

 You can’t access it directly outside the class.

 You must use methods (get_marks, set_marks) to read or modify it


safely.

If you try:

print(obj.__marks)

❌ You’ll get:

AttributeError: 'Student' object has no attribute '__marks'

✅ But internally you could still access:

print(obj._Student__marks)

(not recommended — breaks encapsulation)

🔹 Example 2: Encapsulation Using Getters and Setters (Pythonic


Way)
Python provides a built-in decorator @property to create getters and
setters easily.

class BankAccount:

def __init__(self, balance):

self.__balance = balance

@property

def balance(self): # getter

return self.__balance

@[Link]

def balance(self, amount): # setter

if amount >= 0:

self.__balance = amount

else:

print("Invalid balance!")

account = BankAccount(1000)

print([Link]) # uses getter

[Link] = 5000 # uses setter

print([Link])

📘 Output:

1000

5000

🔐 Access Modifiers in Python (for Encapsulation)

Python doesn’t have true access modifiers like private, protected, or


public (as in Java or C++),
but it follows naming conventions to represent them:
Modifie Synt
Access Description
r ax

Public var Anywhere Default — accessible from anywhere

Protecte Class &


_var Indicated by a single underscore
d Subclass

Only inside Name mangled to prevent accidental


Private __var
class access

🔹 Example 3: Demonstrating Access Levels

class Employee:

def __init__(self):

[Link] = "Public" # Public variable

self._dept = "Protected" # Protected variable

self.__salary = 50000 # Private variable

obj = Employee()

print([Link]) # ✅ Accessible

print(obj._dept) # ⚠️Accessible (but should be used in subclass only)

# print(obj.__salary) # ❌ Error (private)

print(obj._Employee__salary) # ✅ Works, but not recommended

📘 Output:

Public

Protected

50000

🧩 Why Encapsulation Matters

Benefit Explanation

✅ Data Protection Sensitive data (like passwords or balance) can’t be


Benefit Explanation

modified directly.

✅ Code
Changes in internal logic won’t affect outside code.
Maintainability

✅ Flexibility Controlled access via getter/setter allows validation.

✅ Reusability Encapsulated classes are easier to reuse and test.

🧠 Encapsulation vs Abstraction

Concept Encapsulation Abstraction

Binding data and methods


Hiding implementation details
Meaning together; hiding internal
and showing only functionality.
data.

How data is stored and How data is used and


Focus
protected. presented.

Implementati Through access modifiers Through abstract classes and


on and getters/setters. interfaces.

🔹 Example 4: Real-Life Analogy

Think of a capsule medicine 💊

 The outer shell = the class (encapsulation)

 The medicine inside = data (private variables)

 You can’t touch the medicine directly — only take it through


proper method (getter/setter).

💬 In Summary

Key Concept Description

Encapsulati Binding of data and functions that operate on data


on in one unit.

Purpose Data protection and controlled access.


Key Concept Description

Access
Achieved using _ and __ prefixes.
Control

Tools Getters, Setters, and @property.

Foundation of OOP and a key to secure,


Relation
maintainable code.

Would you like me to generate a PDF (with diagrams showing how


encapsulation works and access levels comparison)?

You said:

getter and setter

ChatGPT said:

🧠 Getter and Setter in Python (Detailed Explanation)

⚙️Definition

In Object-Oriented Programming (OOP),


getters and setters are special methods used to access (get) and
modify (set) the value of private (encapsulated) variables safely.

They provide controlled access to class attributes — preventing direct


modification and maintaining data integrity.

🧩 Why We Need Getter and Setter

In Python, all class attributes are public by default, meaning they can be
accessed or modified directly:

class Student:

def __init__(self, name, marks):

[Link] = name

[Link] = marks

obj = Student("Abhay", 95)

print([Link]) # Accessible directly


[Link] = 9999 # Can modify directly

🛑 This breaks encapsulation — anyone can change internal data freely.


✅ Solution → Use getter and setter methods for controlled access.

🔹 Example 1: Manual Getter and Setter

class Student:

def __init__(self, name, marks):

self.__name = name

self.__marks = marks # private variable

# getter method

def get_marks(self):

return self.__marks

# setter method

def set_marks(self, marks):

if 0 <= marks <= 100:

self.__marks = marks

else:

print("Invalid Marks! Must be between 0 and 100.")

obj = Student("Abhay", 85)

print(obj.get_marks()) # ✅ use getter

obj.set_marks(92) # ✅ use setter

print(obj.get_marks())

obj.set_marks(200) # ❌ invalid value

📘 Output:

85
92

Invalid Marks! Must be between 0 and 100.

🔍 Explanation

 __marks is private (encapsulated).

 get_marks() safely retrieves the value.

 set_marks() safely updates it with validation.

If someone tries:

obj.__marks = 999

Python will not modify the real attribute (it creates a new one).
The real data remains protected inside _Student__marks.

🔹 Example 2: Pythonic Way (Using @property Decorators)

Python offers a cleaner way to define getters and setters using the
@property decorator.

class Student:

def __init__(self, name, marks):

self.__name = name

self.__marks = marks

@property

def marks(self): # getter

return self.__marks

@[Link]

def marks(self, value): # setter

if 0 <= value <= 100:

self.__marks = value

else:

print("Invalid Marks! Must be between 0 and 100.")


obj = Student("Abhay", 90)

print([Link]) # getter called automatically

[Link] = 95 # setter called automatically

print([Link])

[Link] = 150 # invalid value

📘 Output:

90

95

Invalid Marks! Must be between 0 and 100.

✅ Advantages of @property Approach

Without @property With @property

obj.get_marks() [Link]

obj.set_marks(95) [Link] = 95

Verbose and less


Cleaner and Pythonic syntax
readable

Native to Python’s design


Similar to Java style
philosophy

🔹 Example 3: Getter Only (Read-Only Property)

If you only define a getter, the variable becomes read-only:

class BankAccount:

def __init__(self, balance):

self.__balance = balance

@property

def balance(self): # only getter, no setter

return self.__balance
acc = BankAccount(1000)

print([Link]) # ✅ works

# [Link] = 2000 # ❌ AttributeError (no setter)

📘 Output:

1000

🔹 Example 4: Setter with Validation

class Employee:

def __init__(self, salary):

self.__salary = salary

@property

def salary(self):

return self.__salary

@[Link]

def salary(self, value):

if value > 0:

self.__salary = value

else:

print("Salary must be positive!")

emp = Employee(30000)

[Link] = 35000 # valid

print([Link])

[Link] = -1000 # invalid

📘 Output:
35000

Salary must be positive!

🔐 Summary Table

Concept Description Example

Method that returns the value of a


Getter @property
private variable

Method that modifies a private variable


Setter @[Link]
safely

Converts a method into a property for


@property [Link]
attribute-style access

Encapsulati Binding of data and methods with Using getters and


on restricted access setters

🧠 Key Takeaways

 Getters and setters protect data from direct modification.

 @property is the Pythonic way to use them.

 They help enforce validation and data integrity.

You might also like