ವಿಷಯಕ್ಕೆ ತೆರಳಿ

ಎನ್‌ಕ್ಯಾಪ್ಸುಲೇಶನ್ (Encapsulation)

ಎನ್‌ಕ್ಯಾಪ್ಸುಲೇಶನ್ (Encapsulation) ಎನ್ನುವುದು ಆಬ್ಜೆಕ್ಟ್-ಓರಿಯೆಂಟೆಡ್ ಪ್ರೋಗ್ರಾಮಿಂಗ್‌ನ (OOP) ಒಂದು ಮೂಲಭೂತ ತತ್ವ. ಇದರರ್ಥ, ಡೇಟಾ (ಗುಣಲಕ್ಷಣಗಳು) ಮತ್ತು ಆ ಡೇಟಾದ ಮೇಲೆ ಕಾರ್ಯನಿರ್ವಹಿಸುವ ಮೆಥಡ್‌ಗಳನ್ನು ಒಂದೇ ಯೂನಿಟ್‌ನಲ್ಲಿ (ಅಂದರೆ, ಕ್ಲಾಸ್‌ನಲ್ಲಿ) ಒಟ್ಟಿಗೆ ಕಟ್ಟುವುದು.

ಎನ್‌ಕ್ಯಾಪ್ಸುಲೇಶನ್‌ನ ಮುಖ್ಯ ಉದ್ದೇಶವೆಂದರೆ ಡೇಟಾವನ್ನು ನೇರ ಪ್ರವೇಶದಿಂದ ರಕ್ಷಿಸುವುದು ಮತ್ತು ಅದನ್ನು ನಿಯಂತ್ರಿತ ರೀತಿಯಲ್ಲಿ ಮಾತ್ರ ಬದಲಾಯಿಸಲು ಅನುಮತಿಸುವುದು. ಇದನ್ನು "ಡೇಟಾ ಹೈಡಿಂಗ್" (Data Hiding) ಎಂದೂ ಕರೆಯುತ್ತಾರೆ.

ಎನ್‌ಕ್ಯಾಪ್ಸುಲೇಶನ್ ಅನ್ನು ಏಕೆ ಬಳಸಬೇಕು?

  • ಡೇಟಾ ಸುರಕ್ಷತೆ: ಆಬ್ಜೆಕ್ಟ್‌ನ ಆಂತರಿಕ ಸ್ಥಿತಿಯನ್ನು (internal state) ಹೊರಗಿನ ಪ್ರಪಂಚದಿಂದ ಮರೆಮಾಡುತ್ತದೆ. ಇದು ಡೇಟಾವನ್ನು ಅನಧಿಕೃತವಾಗಿ ಬದಲಾಯಿಸುವುದನ್ನು ತಡೆಯುತ್ತದೆ.
  • ನಿಯಂತ್ರಿತ ಪ್ರವೇಶ: ಡೇಟಾವನ್ನು ಓದಲು ಅಥವಾ ಬದಲಾಯಿಸಲು ನಾವು ಪಬ್ಲಿಕ್ ಮೆಥಡ್‌ಗಳನ್ನು (ಗೆಟ್ಟರ್‌ಗಳು ಮತ್ತು ಸೆಟ್ಟರ್‌ಗಳು) ಒದಗಿಸಬಹುದು. ಈ ಮೆಥಡ್‌ಗಳಲ್ಲಿ ನಾವು ವ್ಯಾಲಿಡೇಶನ್ ಲಾಜಿಕ್ ಅನ್ನು ಸೇರಿಸಬಹುದು.
  • ನಿರ್ವಹಣೆ ಮತ್ತು ನಮ್ಯತೆ: ಕ್ಲಾಸ್‌ನ ಆಂತರಿಕ ರಚನೆಯನ್ನು ಬದಲಾಯಿಸಿದರೂ, ಹೊರಗಿನ ಕೋಡ್‌ಗೆ ಯಾವುದೇ ಪರಿಣಾಮ ಬೀರುವುದಿಲ್ಲ, ಎಲ್ಲಿಯವರೆಗೆ ಪಬ್ಲಿಕ್ ಮೆಥಡ್‌ಗಳು ಬದಲಾಗುವುದಿಲ್ಲವೋ ಅಲ್ಲಿಯವರೆಗೆ.
  • ಕೋಡ್ ಸ್ಪಷ್ಟತೆ: ಕ್ಲಾಸ್ ಅನ್ನು ಹೇಗೆ ಬಳಸಬೇಕು ಎಂಬುದನ್ನು ಸ್ಪಷ್ಟಪಡಿಸುತ್ತದೆ.

ಪೈಥಾನ್‌ನಲ್ಲಿ ಎನ್‌ಕ್ಯಾಪ್ಸುಲೇಶನ್

ಪೈಥಾನ್‌ನಲ್ಲಿ, ಇತರ ಭಾಷೆಗಳಾದ ಜಾವಾ ಅಥವಾ C++ ನಲ್ಲಿರುವಂತೆ public, private, protected ಎಂಬ ಕೀವರ್ಡ್‌ಗಳಿಲ್ಲ. ಬದಲಾಗಿ, ಪೈಥಾನ್‌ನಲ್ಲಿ ಪ್ರವೇಶವನ್ನು ನಿಯಂತ್ರಿಸಲು ಕೆಲವು ಸಂಪ್ರದಾಯಗಳನ್ನು (conventions) ಬಳಸಲಾಗುತ್ತದೆ.

  1. ಪಬ್ಲಿಕ್ (Public): ಯಾವುದೇ ಅಂಡರ್‌ಸ್ಕೋರ್ ಇಲ್ಲದ ಗುಣಲಕ್ಷಣಗಳು ಮತ್ತು ಮೆಥಡ್‌ಗಳು. ಇವುಗಳನ್ನು ಕ್ಲಾಸ್‌ನ ಹೊರಗಿನಿಂದಲೂ ನೇರವಾಗಿ ಪ್ರವೇಶಿಸಬಹುದು.
  2. ಪ್ರೊಟೆಕ್ಟೆಡ್ (Protected): ಒಂದು ಅಂಡರ್‌ಸ್ಕೋರ್ (_) ನಿಂದ ಪ್ರಾರಂಭವಾಗುವ ಗುಣಲಕ್ಷಣಗಳು. ಇದು ಒಂದು ಸೂಚನೆ, ಅಂದರೆ "ಈ ಅಟ್ರಿಬ್ಯೂಟ್ ಅನ್ನು ಕ್ಲಾಸ್ ಮತ್ತು ಅದರ ಸಬ್‌ಕ್ಲಾಸ್‌ಗಳ ಒಳಗೆ ಮಾತ್ರ ಬಳಸಬೇಕು, ಹೊರಗೆ ಬಳಸಬೇಡಿ". ಆದರೆ ಪೈಥಾನ್ ಇದನ್ನು ತಾಂತ್ರಿಕವಾಗಿ ತಡೆಯುವುದಿಲ್ಲ.
  3. ಪ್ರೈವೇಟ್ (Private): ಎರಡು ಅಂಡರ್‌ಸ್ಕೋರ್ (__) ಗಳಿಂದ ಪ್ರಾರಂಭವಾಗುವ ಗುಣಲಕ್ಷಣಗಳು. ಪೈಥಾನ್ ಇವುಗಳನ್ನು ನೇರವಾಗಿ ಪ್ರವೇಶಿಸುವುದನ್ನು ತಡೆಯಲು "ನೇಮ್ ಮ್ಯಾಂಗ್ಲಿಂಗ್" (Name Mangling) ಎಂಬ ತಂತ್ರವನ್ನು ಬಳಸುತ್ತದೆ.

ಪಬ್ಲಿಕ್, ಪ್ರೊಟೆಕ್ಟೆಡ್ ಮತ್ತು ಪ್ರೈವೇಟ್ ಉದಾಹರಣೆ

class Employee:
    def __init__(self, name, salary, project):
        self.name = name          # ಪಬ್ಲಿಕ್ ಗುಣಲಕ್ಷಣ
        self._project = project   # ಪ್ರೊಟೆಕ್ಟೆಡ್ ಗುಣಲಕ್ಷಣ
        self.__salary = salary    # ಪ್ರೈವೇಟ್ ಗುಣಲಕ್ಷಣ

    def show(self):
        print(f"ಹೆಸರು: {self.name}")
        print(f"ಪ್ರಾಜೆಕ್ಟ್: {self._project}")
        print(f"ಸಂಬಳ (ಪ್ರೈವೇಟ್): {self.__salary}")

# ಆಬ್ಜೆಕ್ಟ್ ರಚಿಸುವುದು
emp = Employee("ಮಹಾಲಕ್ಷ್ಮಿ", 50000, "ವೆಬ್‌ಸೈಟ್ ಡೆವಲಪ್‌ಮೆಂಟ್")

# ಪಬ್ಲಿಕ್ ಗುಣಲಕ್ಷಣವನ್ನು ಪ್ರವೇಶಿಸುವುದು
print(f"ಪಬ್ಲಿಕ್ ಹೆಸರು: {emp.name}")

# ಪ್ರೊಟೆಕ್ಟೆಡ್ ಗುಣಲಕ್ಷಣವನ್ನು ಪ್ರವೇಶಿಸುವುದು (ಶಿಫಾರಸು ಮಾಡುವುದಿಲ್ಲ)
print(f"ಪ್ರೊಟೆಕ್ಟೆಡ್ ಪ್ರಾಜೆಕ್ಟ್: {emp._project}")

# ಪ್ರೈವೇಟ್ ಗುಣಲಕ್ಷಣವನ್ನು ನೇರವಾಗಿ ಪ್ರವೇಶಿಸಲು ಪ್ರಯತ್ನಿಸುವುದು
try:
    print(emp.__salary)
except AttributeError as e:
    print(f"ದೋಷ: {e}")

# ಪ್ರೈವೇಟ್ ಗುಣಲಕ್ಷಣವನ್ನು ಪ್ರವೇಶಿಸಲು ಪೈಥಾನ್ ಬಳಸುವ 'ನೇಮ್ ಮ್ಯಾಂಗ್ಲಿಂಗ್'
# ಇದನ್ನು _ClassName__attributeName ಎಂದು ಪ್ರವೇಶಿಸಬಹುದು (ಆದರೆ ಇದು ಒಳ್ಳೆಯ ಅಭ್ಯಾಸವಲ್ಲ)
print(f"ನೇಮ್ ಮ್ಯಾಂಗ್ಲಿಂಗ್ ಮೂಲಕ ಸಂಬಳ: {emp._Employee__salary}")

# ಪಬ್ಲಿಕ್ ಮೆಥಡ್ ಮೂಲಕ ಪ್ರೈವೇಟ್ ಡೇಟಾವನ್ನು ತೋರಿಸುವುದು
emp.show()
ಔಟ್‌ಪುಟ್:
ಪಬ್ಲಿಕ್ ಹೆಸರು: ಮಹಾಲಕ್ಷ್ಮಿ
ಪ್ರೊಟೆಕ್ಟೆಡ್ ಪ್ರಾಜೆಕ್ಟ್: ವೆಬ್‌ಸೈಟ್ ಡೆವಲಪ್‌ಮೆಂಟ್
ದೋಷ: 'Employee' object has no attribute '__salary'
ನೇಮ್ ಮ್ಯಾಂಗ್ಲಿಂಗ್ ಮೂಲಕ ಸಂಬಳ: 50000
ಹೆಸರು: ಮಹಾಲಕ್ಷ್ಮಿ
ಪ್ರಾಜೆಕ್ಟ್: ವೆಬ್‌ಸೈಟ್ ಡೆವಲಪ್‌ಮೆಂಟ್
ಸಂಬಳ (ಪ್ರೈವೇಟ್): 50000

ಗೆಟ್ಟರ್‌ಗಳು ಮತ್ತು ಸೆಟ್ಟರ್‌ಗಳು (Getters and Setters)

ಪ್ರೈವೇಟ್ ಗುಣಲಕ್ಷಣಗಳನ್ನು ನಿಯಂತ್ರಿತ ರೀತಿಯಲ್ಲಿ ಪ್ರವೇಶಿಸಲು ಮತ್ತು ಬದಲಾಯಿಸಲು ನಾವು ಗೆಟ್ಟರ್ (getter) ಮತ್ತು ಸೆಟ್ಟರ್ (setter) ಮೆಥಡ್‌ಗಳನ್ನು ಬಳಸುತ್ತೇವೆ.

  • ಗೆಟ್ಟರ್ (Getter): ಪ್ರೈವೇಟ್ ಗುಣಲಕ್ಷಣದ ಮೌಲ್ಯವನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ.
  • ಸೆಟ್ಟರ್ (Setter): ಪ್ರೈವೇಟ್ ಗುಣಲಕ್ಷಣದ ಮೌಲ್ಯವನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ. ಇಲ್ಲಿ ನಾವು ವ್ಯಾಲಿಡೇಶನ್ ಲಾಜಿಕ್ ಅನ್ನು ಸೇರಿಸಬಹುದು.

ಉದಾಹರಣೆ:

class Student:
    def __init__(self, name, age):
        self.name = name
        self.__age = age  # ವಯಸ್ಸನ್ನು ಪ್ರೈವೇಟ್ ಮಾಡುವುದು

    # ವಯಸ್ಸನ್ನು ಪಡೆಯಲು ಗೆಟ್ಟರ್ ಮೆಥಡ್
    def get_age(self):
        return self.__age

    # ವಯಸ್ಸನ್ನು ಬದಲಾಯಿಸಲು ಸೆಟ್ಟರ್ ಮೆಥಡ್
    def set_age(self, age):
        if age > 0:
            self.__age = age
        else:
            print("ದಯವಿಟ್ಟು ಸರಿಯಾದ ವಯಸ್ಸನ್ನು ನಮೂದಿಸಿ.")

# ಆಬ್ಜೆಕ್ಟ್ ರಚಿಸುವುದು
s1 = Student("ನಿಶ್ಚಲ", 20)

# ಗೆಟ್ಟರ್ ಬಳಸಿ ವಯಸ್ಸನ್ನು ಪಡೆಯುವುದು
print(f"{s1.name}ಳ ವಯಸ್ಸು: {s1.get_age()}")

# ಸೆಟ್ಟರ್ ಬಳಸಿ ವಯಸ್ಸನ್ನು ಬದಲಾಯಿಸುವುದು
s1.set_age(21)
print(f"ಹೊಸ ವಯಸ್ಸು: {s1.get_age()}")

# ತಪ್ಪು ಮೌಲ್ಯವನ್ನು ಸೆಟ್ ಮಾಡಲು ಪ್ರಯತ್ನಿಸುವುದು
s1.set_age(-5)
print(f"ನಕಾರಾತ್ಮಕ ಮೌಲ್ಯದ ನಂತರ ವಯಸ್ಸು: {s1.get_age()}")
ಔಟ್‌ಪುಟ್:
ನಿಶ್ಚಲಳ ವಯಸ್ಸು: 20
ಹೊಸ ವಯಸ್ಸು: 21
ದಯವಿಟ್ಟು ಸರಿಯಾದ ವಯಸ್ಸನ್ನು ನಮೂದಿಸಿ.
ನಕಾರಾತ್ಮಕ ಮೌಲ್ಯದ ನಂತರ ವಯಸ್ಸು: 21
ಈ ಉದಾಹರಣೆಯಲ್ಲಿ, set_age ಮೆಥಡ್, ವಯಸ್ಸು 0ಕ್ಕಿಂತ ಹೆಚ್ಚಿದ್ದರೆ ಮಾತ್ರ ಅದನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ. ಇದು ನಮ್ಮ ಡೇಟಾವನ್ನು ಅಮಾನ್ಯ ಮೌಲ್ಯಗಳಿಂದ ರಕ್ಷಿಸುತ್ತದೆ. ಇದು ಎನ್‌ಕ್ಯಾಪ್ಸುಲೇಶನ್‌ನ ಶಕ್ತಿಯಾಗಿದೆ.