Objects And Classes in Python
Python program တွေကို ရေးတဲ့အခါမှာ အဓိက အသုံးပြုတဲ့နည်းလမ်းတစ်ခုက Object-Oriented Programming (OOP) ဖြစ်ပါတယ်။ OOP ဆိုတာ Program တွေကို နားလည်ရ၊ ထိန်းသိမ်းရလွယ်အောင် ကုဒ်တွေကို သက်ဆိုင်ရာ Object တွေ အလိုက် စုစည်းပြီး အသုံးပြုတာ ဖြစ်ပါတယ်။ ဒီ Post မှာ တော့ OOP concept ရဲ့ အခြေခံတွေဖြစ်တဲ့ Object နဲ့ Class တွေကို လေ့လာသွားမှာ ဖြစ်ပါတယ်။
Objects & Classes
Python မှာ သုံးနေတဲ့ အရာရာတိုင်းက Object တွေပါ။ Object ဆိုတာ Variable နဲ့ Function တွေကို စုစည်းပေးထားတာဖြစ်ပါတယ်။ Object တွေကို အမျိုးအစား (Class) တွေခွဲထားပါတယ်။ Object class ပေါ်မူတည်ပြီး အဲဒီ Object ရဲ့ တန်ဖိုးနဲ့ လုပ်နိုင်တဲ့ Operation တွေ ကွဲပြားသွားပါတယ်။ (e.g., Integer, String, List, Dictionary)
type()-function နဲ့ ကြည့်လိုက်ရင် Object တစ်ခုရဲ့ Class ကို သိနိုင်ပါတယ်။ Object Class ဆိုတာ ပုံစံခွက် (Template) တစ်ခုလို့ ယူဆနိုင်ပါတယ်။ သူက Object တစ်ခုကို ဘယ်လိုတည်ဆောက်ရမယ်ဆိုတဲ့ အခြေခံပုံစံကို သတ်မှတ်ပေးပါတယ်။
Attributes and Methods
Python ထဲက Object တွေကို ပြင်ပက အရာဝတ္ထုတွေလိုပဲ ယူဆနိုင်ပါတယ်။ ပတ်ဝန်းကျင်မှာရှိတဲ့ စာအုပ်၊ ဖုန်း၊ ကား၊ အိမ် စတာတွေကို Object Class တွေလို့ သတ်မှတ်နိုင်ပါတယ်။ ဒီ Object Class တစ်ခုစီမှာ သူ့ရဲ့ ကိုယ်ပိုင်တန်ဖိုး နဲ့ ကိုယ်ပိုင်လုပ်ဆောင်ချက်တွေ ရှိကြပါတယ်။ Phone class မှာဆိုရင် Color, Size, RAM စတာတွေက တန်ဖိုး/အရည်အသွေး (Attribute) တွေဖြစ်ပြီး Message, Voice Call, Video Call စတာတွေက ဖုန်းတစ်လုံးက ပြုလုပ်နိုင်တဲ့ လုပ်ဆောင်ချက် (Method) တွေ ဖြစ်ပါတယ်။ Method နဲ့ Attribute တွေက ဖုန်းတစ်လုံးနဲ့ တစ်လုံး ကွာခြားနိုင်ပေမယ့် သူတို့အကုန်လုံးကတော့ Phone ဆိုတဲ့ Object Class ထဲမှာ ရှိကြပါတယ်။ ဒီလို Class တစ်ခုတည်းအောက်မှာ ရှိတဲ့ ဖုန်းတစ်လုံးစီကိုတော့ Phone Object လို့ ခေါ်နိုင်ပါတယ်။ Attribute ဆိုတာ Object နဲ့ သက်ဆိုင်တဲ့ Data တွေဖြစ်ပြီး Method ကတော့ Object ကနေလုပ်ပေးနိုင်တဲ့ လုပ်ဆောင်ချက် တွေဖြစ်ပါတယ်။ အခေါ်အဝေါ်မတူပေမယ့် အမှန်ကတော့ Object ကနေ တစ်ဆင့်ယူသုံးရတဲ့ Variable တွေနဲ့ Function တွေပါပဲ။ Object တစ်ခုမှာပါတဲ့ Attribute နဲ့ Method တွေကို Dot Operator ( . ) နဲ့ ယူသုံးရပါတယ်။ (syntax: obj.attribute, obj.method())
Built-in Classes
String, List, Integer စတာတွေက Python မှာ Define လုပ်ပြီးသား Object class တွေဖြစ်ပါတယ်။ Integer variable တစ်ခုကို type()-function နဲ့ ကြည့်လိုက်ရင် Integer class ထဲမှာ ပါတယ်ဆိုတာကို ပြပေးမှာပါ။ ဒါကြောင့် ဒီ Variable က Integer class မှာပါတဲ့ Attribute တွေကို ယူသုံးနိုင်ပါတယ်။ String, List တွေမှာသုံးနေတဲ့ upper(), find(), append() စတာတွေက Object တစ်ခုစီစီမှာပါတဲ့ Method တွေဖြစ်ပါတယ်။
num = 10
print(type(num)) # <class 'int'>
print(num.real) # 10
print(num.imag) # 0
message = 'Hello Python'
print(message.startswith('h')) # False
print(message.find('P')) # 6
odds = list()
odds.append(3)
odds.append(7)
odds.insert(0, 1)
odds.pop()
print(odds) # [1, 3]
Attribute နဲ့ Method တွေက Object တစ်ခုစီရဲ့ အတွင်းပိုင်း လုပ်ဆောင်ချက် တွေကို သိမ်းပေးထားတာကို တွေ့နိုင်ပါတယ်။ ကိုယ်သုံးချင်တဲ့ Feature ကို Program ထဲမှာ ယူသုံးရုံပါပဲ။ find()-method ထဲမှာ ဘယ်လိုရှာလဲ၊ insert()-method က item တွေကို ဘယ်လိုထည့်ပေးလဲဆိုတာ သိစရာမလိုပါဘူး။ ဖုန်းခေါ်တဲ့အခါ ဖုန်းတစ်လုံးနဲ့ တစ်လုံး ချိတ်ဆက်ပေးတဲ့ လုပ်ဆောင်ချက်တွေကို ဖုန်းက အကုန်လုပ်တတ်ပြီးသားဖြစ်လို့ User က ဘာမှသိစရာမလိုပါဘူး။ ဒီလို Object ထဲမှာ ရှုပ်ထွေးမှုတွေကို သိမ်းထားပြီး High-level ကနေ အသုံးပြုနိုင်တာကို OOP concept တစ်ခုဖြစ်တဲ့ Abstraction လို့ခေါ်ပါတယ်။
User-defined Objects
ကိုယ်ပိုင် Object တစ်ခုကို တည်ဆောက်ဖို့အတွက် အရင်ဆုံး Class တစ်ခုဖန်တီးရပါမယ်။ Class ထဲမှာ သုံးမယ့် Attribute နဲ့ Method တွေကို Template တစ်ခုအနေနဲ့ သတ်မှတ်ပေးရပါမယ်။ ပြီးတာနဲ့ အဲဒီ Class ကို သုံးပြီး Object instance တည်ဆောက်ပါမယ်။ ရလာတဲ့ Object instance ကို Program ထဲမှာ ဆက်သုံးမှာဖြစ်ပါတယ်။
Defining A New Class (Template)
Class အသစ်တစ်ခု ကို class-keyword နဲ့ သတ်မှတ်ရပါတယ်။ Function တစ်ခုကို Define လုပ်လိုက်တဲ့ အခါမှာ Function ကို တန်းပြီး Run မပေးပါဘူး။ Class ကို Define လုပ်တဲ့အခါမှာလည်း တစ်ကယ့် Object တစ်ခုကို တည်ဆောက်မပေးပါဘူး။ Object တည်ဆောက်တဲ့အခါမှာ သုံးရမယ့် Template ကိုပဲ ထုတ်ပေးတာ ဖြစ်ပါတယ်။
နမူနာအနေနဲ့ Car-object တစ်ခုတည်ဆောက်ကြည့်ပါမယ်။ Function name နဲ့ မတူအောင်လို့ Class name တွေကို CamelCase နဲ့ သတ်မှတ်ရပါတယ်။ (e.g., Phone, Player, CreditCard, AtomicBomb)
class Car:
def __init__(self, speed, model, color):
self.wheels = 4
self.speed = speed
self.model = model
self.color = color
print('A Car object is created.')
def drive(self):
print('Driving at', self.speed, 'mph.')
Car class မှာတော့ Attribute အနေနဲ့ wheels, speed, model နဲ့ color ဆိုပြီး ပါပါမယ်။ အရင်ဆုံးတွေ့ရတဲ့ dunder(double underscore) init()-method ကို Constructor လို့ခေါ်ပါတယ်။ Object တစ်ခုတည်ဆောက်တဲ့ အခါမှာ Python က ဒီ Method ကို ခေါ်ပေးပါတယ်။ ဒါကြောင့် init()-method ထဲမှာ စစချင်း ရှိရမယ့် Attribute တွေကို သတ်မှတ်ပေးနိုင်ပါတယ်။ Wheels-attribute ကိုတော့ ချက်ချင်းသတ်မှတ်ထားပြီး Speed, Model, Color စတာတွေက ကားတစ်စီးနဲ့ တစ်စီး မတူနိုင်တာဖြစ်လို့ Object တည်ဆောက်တဲ့ အခါမှ ထည့်ပေးမှာဖြစ်ပါတယ်။
ရိုးရိုး Function တွေနဲ့ မတူတဲ့အချက်က Method တွေမှာ ပထမဆုံး Parameter အနေနဲ့ self ဆိုတာကို ထည့်ပေးရပါတယ်။ self-variable က လက်ရှိသုံးနေတဲ့ Object ကို ရည်ညွှန်းပါတယ်။ Class အတွင်းမှာ ဆိုရင် self-variable ကနေတစ်ဆင့် Object instance ရဲ့ Attribute နဲ့ Function တွေကို ယူသုံးနိုင်ပါတယ်။ Variable name ကို တော့ကြိုက်ရာထားလို့ရပေမယ့် Convention အဖြစ်နဲ့ self ကိုပဲ သုံးကြပါတယ်။
Constructing An Object (Instance)
Program ထဲမှာ တစ်ကယ်အသုံးပြုနိုင်မယ့် Car object တစ်ခုတည်ဆောက်ကြည့်ပါမယ်။
suv = Car(60, 'suv', 'black') # A Car object is created.
print(type(suv)) # <class '__main__.Car'>
Function ခေါ်တာနဲ့ Syntax အတူတူပါပဲ။ Class name နောက်မှာ ကွင်းစ၊ ကွင်းပိတ်နဲ့ ထည့်ထားတဲ့ တန်ဖိုးတွေက init()-method အတွက်လိုအပ်တဲ့ Argument တွေဖြစ်ပါတယ်။ init()-method ထဲက print()-function အလုပ်လုပ်တာကို တွေ့ရမှာပါ။ ဒါဟာ Object တည်ဆောက်လိုက်တဲ့ အခါ init()-method ကို Python က တန်းခေါ်ပေးထားလို့ ဖြစ်ပါတယ်။ type()-Function ထဲကို ထည့်ကြည့်ရင် Car class ကို တွေ့နိုင်ပါတယ်။
Car object ရဲ့ Attribute နဲ့ Method တွေကို class အတွင်းမှာ self-variable နဲ့သုံးရသလို အပြင်မှာ ယူသုံးချင်ရင် Instance variable ကနေတစ်ဆင့် သုံးရပါတယ်။
print(suv.model) # suv
print(suv.color) # black
print(suv.wheels) # 4
suv.drive() # Driving at 60 mph.
ဒီလိုသုံးလို့ရအောင် init()-method ထဲမှာ Object instance (self) နဲ့ Attribute တန်ဖိုးတွေကို တွဲပြီး Object တည်ဆောက်ပေးတာဖြစ်ပါတယ်။ drive()-method ရဲ့ Parameter ထဲမှာ self ဆိုပြီး ပြထားပေမယ့် သုံးတဲ့ အခါမှာ ဘာမှထည့်ပေးမထားတာကို တွေ့ရမှာပါ။ Method တစ်ခုကို ခေါ်တဲ့အခါမှာ ခေါ်တဲ့ Object ကို ပထမ Argument အနေနဲ့ သူ့အလိုလို ထည့်ပေးပါတယ်။ ဒါကြောင့် အပေါ်က suv.drive() ဆိုတာက Car.drive(suv) နဲ့ အဓိပ္ပါယ်အတူတူပါပဲ။
Object attribute တွေကိုလည်း သာမန် Variable တွေလိုပဲ ပြောင်းလဲနိုင်ပါတယ်။
suv.color = 'white'
print(sub.color) # white
suv.speed = 80
suv.drive() # Driving at 80 mph.
Object တည်ဆောက်လိုက်ရင် ကုဒ်တွေကို စုစည်းပြီးသားဖြစ်လို့ နားလည်ရ၊ ပြုပြင်ရလွယ်သွားပါတယ်။ အခုလို Car object မရှိရင် Program ထဲမှာ ကားတစ်စီးရဲ့ speed, model, color စတဲ့ Data တွေကို စုစည်းထားဖို့ မလွယ်ပါဘူး။ တစ်ကယ်လို့ နောက်ထပ်ကားတွေ ထပ်တိုးလာမယ်ဆိုရင် ပိုပြီး ထိန်းသိမ်းရ ခက်ခဲလာမှာပါ။
Multiple Instances
Class ဆိုတာ Template တစ်ခု ဖြစ်တဲ့အတွက် Attribute မတူတဲ့ Object တွေကို လိုအပ်သလို တည်ဆောက်နိုင်ပါတယ်။
pickup = Car(50, 'pick up', 'yellow') # A Car object is created.
van = Car(60, 'van', 'white') # A Car object is created.
truck = Car(40, 'truck', 'red') # A Car object is created.
Object တစ်ခုစီက Class တစ်ခုတည်းက လာတာ ဖြစ်လို့ လိုအပ်တဲ့ Argument တွေ၊ လုပ်ဆောင်ချက်တွေက အတူတူပဲ ဖြစ်ပါတယ်။
print(van.color) # white
van.color = 'blue'
print(van.color) # blue
pickup.drive() # Driving at 50 mph.
pickup.speed = 90
pickup.drive() # Driving at 90 mph.
truck.wheels = 10
ဒီလို Object instance တွေအများကြီးကို လွယ်လွယ်ကူကူ တည်ဆောက်နိုင်တာက Class ရဲ့ အဓိကအသုံးဝင်တဲ့ Feature ဖြစ်ပါတယ်။ ကုဒ်တွေကို ထပ်ခါထပ်ခါရေးစရာမလိုတော့အတွက် DRY Principle (Don't Repeat Yourself) ကိုလည်း လိုက်နာပြီးသားဖြစ်ပါတယ်။
Derived Classes
ရှိပြီးသား Class တစ်ခုကို အခြေခံပြီး Class အသစ်တွေ ထပ်ဖန်တီးတာကို Inheritance လို့ခေါ်ပါတယ်။ အသစ်ရလာတဲ့ Child class က Parent class ရဲ့ Attributes တွေကို လက်ခံအသုံးပြုနိုင်တဲ့အပြင် လိုအပ်သလို Override လုပ်နိုင်ပါတယ်။
Inheritance လုပ်ရင် Parent class ကို class name နောက်မှာ ကွင်းစ၊ ကွင်းပိတ်နဲ့ ထည့်ပေးရပါတယ်။ အပေါ်ကရေးခဲ့တဲ့ Car class ကို သုံးပြီး class အသစ်တည်ဆောက်ကြည့်ပါမယ်။
class FlyingCar(Car):
def fly(self):
print('Flying at', self.speed, 'mph in the air.')
jumbo = FlyingCar(80, 'aero', 'black')
# A Car object is created.
jumbo.drive() # Driving at 80 mph.
jumbo.fly() # Flying at 80 mph in the air.
print(jumbo.wheels) # 4
print(jumbo.color) # black
FlyingCar-class မှာဆိုရင် fly()-method တစ်ခုပဲ ရေးထားပါတယ်။ ဒါပေမယ့် Car-class ကို Inherit လုပ်ထားတာဖြစ်လို့ Car object မှာထည့်ရမယ့် Argument တွေထည့်ပေးရပြီး Car object ရဲ့ Feature တွေကို သုံးလို့ရပါတယ်။ ဒါကြောင့် init(), drive() စတာတွေကို ထည့်ပေးစရာ မလိုတာပါ။
Conclusion
Object တွေနဲ့ ပတ်သက်ပြီး အဓိကမှတ်ထားရမယ့် အချက်တွေကို ထပ်ဖော်ပြပေးပါမယ်။
- Object - Variable နဲ့ Function တွေကို စုစည်းပေးထားတဲ့ အရာပါ။
- Class - Object တစ်ခုတည်ဆောက်တဲ့နေရာမှာ သုံးတဲ့ Template ဖြစ်ပါတယ်။ Object ရဲ့ အခြေခံပုံစံကို သတ်မှတ်ပေးပါတယ်။
- Attribute - Object တစ်ခုနဲ့ သက်ဆိုင်တဲ့တန်ဖိုး (Variable) တွေ ဖြစ်ပါတယ်။ init() ဆိုတဲ့ Special function ထဲမှာ Object နဲ့ ချိတ်ဆက်ပေးရပါတယ်။
- Method - Object ကနေတစ်ဆင့် သုံးနိုင်တဲ့ Function တွေပါ။ Instance ကို First Parameter အဖြစ် လက်ခံပါတယ်။
- Instance - Class ကို သုံးပြီး ရလာတဲ့ Object ဖြစ်ပါတယ်။
- Abstraction - အသေးစိတ်လုပ်ဆောင်ချက်တွေကို Object ထဲမှာ သိမ်းထားပြီး High-level interface ထုတ်ပေးတာ ဖြစ်ပါတယ်။
- Inheritance - ရှိပြီးသား Class ကို အခြေခံပြီး Class အသစ် ဖန်တီးတာဖြစ်ပါတယ်။
- Child class - Inherit လုပ်ပြီး တည်ဆောက်ထားတဲ့ Class အသစ်ပါ။
- Parent class - Child class တွေအခြေခံထားတဲ့ Base class ဖြစ်ပါတယ်။
ဒီ Post မှာတော့ Object တည်ဆောက်ပုံနဲ့ အသုံးပြုပုံတွေကို လေ့လာခဲ့တာဖြစ်ပါတယ်။ Object-Oriented Programming ကို လေ့လာတဲ့နေရာမှာ ဒါတွေကို သေသေချာချာနားလည်ထားဖို့လိုပါတယ်။ Object နဲ့ Class တွေကို ကျွမ်းကျွမ်းကျင်ကျင်သုံးနိုင်ရင် ပိုမိုထိရောက်ကောင်းမွန်တဲ့ Python Program တွေ ရေးနိုင်လာမှာ ဖြစ်ပါတယ်။