Encapsulation

Code မှာ ဘယ်လို သုံးလဲ

Python မှာ Data Hiding လုပ်တဲ့ သဘောတူညီချက် (Developer တွေ အချင်းချင်း နားလည်တဲ့ သင်္ကေတ) ရှိတယ်။

အဲ့ဒါက Underscore (_) ပဲ။

Attribute (data) တစ်ခုရဲ့ နာမည်ရှေ့မှာ underscore (_) တစ်ခု ထည့်လိုက်ရင်...

အဓိပ္ပာယ်: bro... ဒါက အတွင်း ပစ္စည်း (internal data) နော်။ bro တိုက်ရိုက် မသုံးနဲ့။ ဒါက ကျနော့် Object ရဲ့ အတွင်းရေး။

လို့ ပြောလိုက်တာ။

မဖိုင်း တဲ့နည်း (No Encapsulation)

Bank account တစ်ခု ဆောက် ကြည့်မယ်။

Bad Example - No Encapsulation
class BadBankAccount: def __init__(self, name, balance): self.name = name self.balance = balance # ဒါက အပြင်ကနေ တိုက်ရိုက် သုံးလို့ရတယ် # Object မွေးမယ် my_account = BadBankAccount("My Bro", 1000) print(f"Balance: {my_account.balance}") # 1000 # The Problem # အပြင်ကနေ တစ်ယောက်ယောက်က တိုက်ရိုက် ဝင်သုံးတယ် my_account.balance = -9999999 # ဂျွမ်းထိုးပြီ print(f"New Balance: {my_account.balance}") # -9999999 # Bank account က minus ပြသွားပြီ။ ရှုပ်ကုန်ပြီ။
ပြဿနာ: ဒီနည်းက data ကို တိုက်ရိုက် သုံး လို့ရတဲ့အတွက် မတော်တဆ/တမင် ပျက်စီးသွားနိုင်တယ်။

With Encapsulation

အခု... _ (underscore) သုံးပြီး ဝှက်မယ်။ တံခါးပေါက် (methods) တွေနဲ့ပဲ ဝင်/ထွက် ခိုင်းမယ်။

Good Example - With Encapsulation
class GoodBankAccount: def __init__(self, name, balance): self.name = name self._balance = balance # 1. ဝှက်လိုက်ပြီ (Internal Use Only) # 2. "Public Interface" (တံခါးပေါက်) တွေ ဆောက်မယ် # "Getter" (Data ကို တောင်း ကြည့်ဖို့) def get_balance(self): print("Authenticating user...") # ဒီနေရာမှာ Security အဆင့်တွေ ထည့်လို့ရတယ် return self._balance # "Setter" (Data ကို ပြင်ဖို့) def deposit(self, amount): if amount <= 0: print("bro... positive number ထည့်") return self._balance += amount print(f"Done. New balance: {self._balance}") def withdraw(self, amount): if amount <= 0: print("WTF bro?") return if amount > self._balance: print("Bro... ပိုက်ဆံ မလောက်ဘူး") return self._balance -= amount print(f"Done. New balance: {self._balance}")

အခု သုံးကြည့်မယ်:

Using Encapsulated Class
# Object မွေးမယ် my_account = GoodBankAccount("My Bro", 1000) # တိုက်ရိုက် သုံးလို့ မရတော့ဘူး # print(my_account._balance) # မလုပ် သင့်တဲ့အရာ # တံခါးပေါက် (Methods) ကနေပဲ သုံး မယ် print(f"Current Balance: {my_account.get_balance()}") # 1000 # ပိုက်ဆံ သုံးမယ် my_account.deposit(500) # "Done. New balance: 1500" my_account.withdraw(200) # "Done. New balance: 1300" # တစ်ယောက်ယောက်က သုံးကြည့်မယ် my_account.deposit(-100) # "bro... positive number ထည့်" my_account.withdraw(5000) # "Bro... ပိုက်ဆံ မလောက်ဘူး။" # Safe ဖြစ်သွားပြီ။ # အတွင်းပိုင်း (internal) က _balance ကို တံခါးပေါက် တွေက ကာထားပေးတယ်။ print(f"Final Balance: {my_account.get_balance()}") # 1300 (Safe ဖြစ်နေတယ်)
Safe ဖြစ်: အတွင်းက _balance ကို တံခါးပေါက် တွေက ကာပေးထားတယ်။

Python ရဲ့ အတွေးအခေါ်

Bro... my_account._balance = -9999 လို့ တိုက်ရိုက် ရိုက်ထည့်ရင် ရသေးတာပဲ?

Python မှာ ရပါတယ်။ ဘာလို့လဲဆိုတော့ Python ရဲ့ Vibe က... We are all consenting adults here. (ကျွန်တော်တို့အားလုံးက ခွင့်ပြုချက်နဲ့ ဆောင်ရွက်နေကြတဲ့ လူကြီးတွေပါ။)

သတိ: _ (underscore) က သော့ခတ် လိုက်တာ မဟုတ်ဘူး။ Bro... ဒါ အတွင်းပစ္စည်းနော်။ မထိ နဲ့ လို့ ဆိုင်းဘုတ် ထောင်ထားတာ။

bro က အဲ့ ဆိုင်းဘုတ်ကို ဖတ်ပြီး တမင် ဝင်သုံး... ဂျွမ်းသွားရင်တော့ bro တာဝန်ပဲ။

Double Underscore (__) - Name Mangling

Single underscore (_) က သဘောတူညီချက်ပဲ။ ဒါပေမယ့် bro က တကယ်ကို ကာကွယ်ချင်ရင် double underscore (__) သုံးလို့ရတယ်။

Double Underscore Example
class SecureBankAccount: def __init__(self, name, balance): self.name = name self.__balance = balance # Double underscore သုံးထားတယ် def get_balance(self): return self.__balance def deposit(self, amount): if amount > 0: self.__balance += amount # Object မွေးမယ် secure_account = SecureBankAccount("Secure User", 5000) # တိုက်ရိုက် သုံးကြည့်မယ် try: print(secure_account.__balance) # Error တက်မယ်! except AttributeError as e: print(f"Error: {e}") # AttributeError: 'SecureBankAccount' object has no attribute '__balance' # Methods ကနေတော့ အဆင်ပြေတယ် print(f"Balance: {secure_account.get_balance()}") # 5000

Name Mangling က ဘာလုပ်တာလဲ?

Double underscore (__) သုံးရင် Python က နာမည်ကို အလိုအလျောက် ပြောင်းပေးတယ်။ __balance က _ClassName__balance ဖြစ်သွားတယ်။

Name Mangling Demonstration
# တကယ်တော့ ဒီလို သုံးလို့ရသေးတယ် ဒါပေမယ့် မလုပ်သင့်ဘူး print(secure_account._SecureBankAccount__balance) # 5000 # ဒါက Python က "bro တို့ သိပြီးသား ဖြစ်ပါစေ" ဆိုတဲ့ သဘောပဲ
နည်း:
  • Single underscore (_): သဘောတူညီချက်အတွက် သုံးတယ်
  • Double underscore (__): Name mangling လုပ်ချင်ရင် သုံးတယ် (ကာကွယ်မှု လိုအပ်တဲ့ အခါ)

Encapsulation ကို ဘယ်တော့ သုံးသင့်လဲ?

Example 1: User Authentication System

Password တွေ လုံခြုံအောင် သိမ်းထားချင်တဲ့အခါ။

User Authentication
class User: def __init__(self, username, password): self.username = username self.__password = password # Password ကို ဝှက်ထားတယ် def check_password(self, input_password): # Password စစ်တဲ့ method return self.__password == input_password def change_password(self, old_password, new_password): if self.check_password(old_password): self.__password = new_password print("Password changed successfully!") else: print("Wrong old password!") user = User("john_doe", "secret123") # Password ကို တိုက်ရိုက် ဖတ်လို့ မရဘူး # print(user.__password) # Error! # Method ကနေပဲ check လုပ်ရတယ် print(user.check_password("wrong")) # False print(user.check_password("secret123")) # True

Example 2: Temperature Sensor

Temperature value တွေကို validate လုပ်ချင်တဲ့အခါ။

Temperature Sensor
class TemperatureSensor: def __init__(self): self._temperature = 0 # အတွင်း data self._min_temp = -50 self._max_temp = 150 def get_temperature(self): return self._temperature def set_temperature(self, temp): # Validation လုပ်တယ် if self._min_temp <= temp <= self._max_temp: self._temperature = temp print(f"Temperature set to {temp}°C") else: print(f"Invalid temperature! Must be between {self._min_temp} and {self._max_temp}") sensor = TemperatureSensor() sensor.set_temperature(25) # Temperature set to 25°C sensor.set_temperature(200) # Invalid temperature! sensor.set_temperature(-100) # Invalid temperature! print(f"Current temp: {sensor.get_temperature()}°C") # 25°C

Example 3: Shopping Cart

Shopping cart မှာ item တွေကို ထိန်းချုပ်ချင်တဲ့အခါ။

Shopping Cart
class ShoppingCart: def __init__(self): self._items = [] # Item list ကို ဝှက်ထားတယ် self._total = 0 def add_item(self, item_name, price): if price <= 0: print("Price must be positive!") return self._items.append({'name': item_name, 'price': price}) self._total += price print(f"Added {item_name} - ${price}") def get_total(self): return self._total def get_item_count(self): return len(self._items) cart = ShoppingCart() cart.add_item("Laptop", 1000) cart.add_item("Mouse", 25) cart.add_item("Invalid", -50) # Price must be positive! print(f"Total items: {cart.get_item_count()}") # 2 print(f"Total price: ${cart.get_total()}") # $1025 # List ကို တိုက်ရိုက် ပြင်လို့မရဘူး # cart._items = [] # မလုပ်သင့်
ဘယ်ချိန် Encapsulation သုံးသင့်လဲ:
  • Data ကို validate လုပ်ဖို့ လိုအပ်တဲ့အခါ (ဥပမာ: temperature range, price > 0)
  • Sensitive data တွေ (passwords, personal info) ကို protect လုပ်ချင်တဲ့အခါ
  • Object ရဲ့ internal state ကို တခြားသူတွေ မပြောင်းစေချင်တဲ့အခါ
  • Business logic တွေ enforce လုပ်ချင်တဲ့အခါ (ဥပမာ: withdraw မလုပ်ခင် balance check တာမျိုး)

အနှစ်ချုပ်

  • Encapsulation: Data (Attributes) + Methods (Functions) တွေကို အထုပ် (Bundle) တစ်ခုတည်း (Object) မှာ ထည့် (pack) တာ။
  • Data Hiding: အတွင်း data (Internal Data) တွေကို ဝှက် (Hide) ထားတာ။
  • Why Hide?: တစ်ယောက်ယောက်က သုံးလို့ ရှုပ်ပွ မသွားအောင်၊ safe ဖြစ်အောင် ကာကွယ်ပေးတာ။
  • How in Python?: Attribute ရှေ့မှာ _ (underscore) ထည့်ပြီး ဒါ အတွင်း data လို့ သဘောတူညီချက် ပြ။
  • Double Underscore (__): Name mangling အတွက် သုံးတယ်၊ ပိုလုံခြုံအောင် လုပ်ချင်ရင်။
  • How to Use?: ဝှက် (hidden) ထားတဲ့ data တွေကို သုံး ဖို့ get_...() set_...() (Getter/Setter) လို တံခါးပေါက် (public methods) တွေ ဆောက်ထားပေး။