Encapsulation (ဒေတာနဲ့ method ကို တစ်စုတည်း ထုပ်ပိုးခြင်း)
B3.1: Apply encapsulation by using access modifiers and accessor/mutator methods.
မြန်မာလို: access modifier (ဘယ်ကနေ သုံးခွင့်ရလဲ သတ်မှတ်တဲ့ keyword) တွေနဲ့ accessor/mutator method (attribute ရဲ့ တန်ဖိုးကို ဖတ်ပေးတဲ့ / ပြောင်းပေးတဲ့ method) တွေကို သုံးပြီး encapsulation ကို လက်တွေ့ အသုံးချနိုင်ရပါမယ်။
အဓိက အယူအဆများ
Encapsulation ဆိုတာ ဘာလဲ
Encapsulation ဆိုတာ variable (တန်ဖိုး သိမ်းထားတဲ့ နာမည်ပေးထားတဲ့ နေရာ) တွေနဲ့ method (သီးခြား အလုပ်တစ်ခု လုပ်ပေးတဲ့ code အပိုင်း) တွေကို unit (အစု) တစ်ခုတည်း၊ ဆိုလိုတာက class (object တွေ ဖန်တီးဖို့ ပုံစံခွက်) ထဲမှာ စုထည့်ပြီး variable တွေကို private လုပ်ကာ တိုက်ရိုက် သုံးခွင့်ကို ကန့်သတ်တာပါ။ အပြင်က code က object (class တစ်ခုကနေ ဖန်တီးထားတဲ့ instance) ရဲ့ ဒေတာကို သူ့ရဲ့ public method တွေကနေတစ်ဆင့်ပဲ ကိုင်တွယ်လို့ ရပါတယ်: ဒေတာကို ဘယ်လို ဖတ်မလဲ၊ ဘယ်လို ပြောင်းမလဲဆိုတာကို class ကိုယ်တိုင်က ထိန်းချုပ်ပါတယ်။
ဒီ principle (အခြေခံ သဘောတရား) ကို information hiding (object ရဲ့ အတွင်း ဒေတာကို ဖုံးထားခြင်း) လို့လည်း ခေါ်ပါတယ်: အပြင်က code က class ရဲ့ public interface (အပြင်က code သုံးဖို့ ဖွင့်ပေးထားတဲ့ public method တွေ) ပေါ်မှာပဲ မူတည်ပြီး class အတွင်းမှာ ဒေတာကို ဘယ်လို သိမ်းထားလဲ ဆိုတာပေါ်မှာ ဘယ်တော့မှ မမူတည်ပါဘူး။ ဒါက object ရဲ့ state (object ထဲမှာ လက်ရှိ ရှိနေတဲ့ တန်ဖိုးများ) မှန်ကန်ပြီး ပျက်စီးမသွားအောင် ကာကွယ်ပေးပါတယ်။
အလိုအလျောက် ရောင်းချစက် (vending machine) ကို စဉ်းစားကြည့်ပါ: စက်ထဲကို လက်လှမ်းပြီး ပစ္စည်းတွေကို တိုက်ရိုက် ယူလို့ မရပါဘူး။ စက်က သတ်မှတ်ပေးထားတဲ့ နည်းလမ်းတွေကနေပဲ စက်ကို သုံးရပါတယ်: ပိုက်ဆံ ထည့်၊ ခလုတ် နှိပ်၊ ပစ္စည်း ယူ။ စက်ရဲ့ အတွင်း state (ပစ္စည်း ဘယ်လောက် ကျန်လဲ၊ ပိုက်ဆံ ဘယ်လောက် ရှိလဲ) ကို ဖုံးထားပြီး ကာကွယ်ထားပါတယ်။
ဘာကြောင့် encapsulate လုပ်သလဲ
Encapsulation မရှိရင် ဘယ်နေရာက code မဆို ဘယ် variable ကိုမဆို ဘယ်တန်ဖိုး ဖြစ်ဖြစ် ပြောင်းလို့ ရပါတယ်:
// WITHOUT encapsulation -- attributes are public
public class Recipe {
public String name;
public int servings;
}
Recipe r = new Recipe();
r.servings = -100; // nothing stops this
r.name = ""; // empty string is allowed
# WITHOUT encapsulation - attributes are public (no underscore)
class Recipe():
def __init__(self):
self.name = ""
self.servings = 0
r = Recipe()
r.servings = -100 # nothing stops this
r.name = "" # empty string is allowed
Encapsulation ရှိရင် ဘယ်တန်ဖိုးတွေကို လက်ခံမလဲဆိုတာ class က ထိန်းချုပ်ပါတယ်:
// WITH encapsulation -- attributes are private, access through methods
public class Recipe {
private String name;
private int servings;
public Recipe(String name, int servings) {
setName(name); // the constructor uses the setters,
setServings(servings); // so their checks run here too
}
public String getName() { return name; }
public int getServings() { return servings; }
public void setName(String name) {
if (name != null && name.length() > 0) {
this.name = name;
}
}
public void setServings(int servings) {
if (servings >= 1 && servings <= 50) {
this.servings = servings;
}
}
}
# WITH encapsulation - attributes private (underscore), access through methods
class Recipe():
def __init__(self, name, servings):
self._name = None # start from Java's defaults,
self._servings = 0 # in case a setter refuses the value
self.set_name(name) # the constructor uses the setters,
self.set_servings(servings) # so their checks run here too
def get_name(self):
return self._name
def get_servings(self):
return self._servings
def set_name(self, name):
if name != None and len(name) > 0:
self._name = name
def set_servings(self, servings):
if servings >= 1 and servings <= 50:
self._servings = servings
အပြင်က code က r.servings = -100; လို့ ရေးလို့ မရတော့ပါဘူး: servings က private ဖြစ်ပြီး setServings က 1 ကနေ 50 ကြားမှာ မရှိတဲ့ တန်ဖိုး မှန်သမျှကို လက်မခံပါဘူး။ Constructor (object ဖန်တီးချိန် attribute တွေကို စတင် သတ်မှတ်ပေးတဲ့ method) က field (object ထဲက အချက်အလက် အကွက်) တွေထဲကို ကိုယ်တိုင် တန်ဖိုး မထည့်ဘဲ setter (private attribute ရဲ့ တန်ဖိုးကို ပြောင်းတဲ့ method) တစ်ခုစီကို ခေါ်ပါတယ်။ ဒါကြောင့် object ကို ဖန်တီးတဲ့အခါရော၊ ပြောင်းတဲ့အခါတိုင်းရော စစ်ဆေးချက် အတူတူ run ပါတယ်။ နောက်ပိုင်း စည်းမျဉ်းတွေ ပြောင်းရင် setter ကိုပဲ ပြင်ရပါတယ်။ Setter က လက်မခံတဲ့ တန်ဖိုး ဆိုရင် field က သူ့ရဲ့ default value (သတ်မှတ်မထားရင် သုံးတဲ့ တန်ဖိုး) အတိုင်း ကျန်နေပါတယ် (int အတွက် 0၊ String အတွက် null)။
Encapsulation က အဓိက အားသာချက် လေးခု ပေးပါတယ်:
| အားသာချက် | ဘယ်လို ရလဲ |
|---|---|
| Data hiding (ဒေတာကို ဖုံးကွယ်ထားခြင်း) | Class အတွင်းမှာ ဒေတာ သိမ်းထားပုံကို ဖုံးထားပါတယ်၊ တခြား class တွေက public interface ကနေပဲ ဆက်သွယ် ကိုင်တွယ်ပါတယ် |
| Validation (တန်ဖိုး မှန်မမှန် စစ်ခြင်း) | Setter နဲ့ mutator (attribute ရဲ့ တန်ဖိုးကို ပြောင်းပေးတဲ့ method) တွေက တန်ဖိုးတွေကို လက်မခံခင် မှန်မမှန် စစ်ပါတယ် |
| Flexibility (ပြောင်းလွယ်ပြင်လွယ် ရှိခြင်း) | Class ကို သုံးနေတဲ့ code ကို မထိခိုက်ဘဲ class ရဲ့ အတွင်း implementation (တကယ် အလုပ်လုပ်အောင် ရေးထားတဲ့ code) ကို ပြောင်းလို့ ရပါတယ် |
| Security (လုံခြုံရေး) | Object ရဲ့ state ကို မတော်တဆ ဒါမှမဟုတ် မကောင်းတဲ့ ရည်ရွယ်ချက်နဲ့ ပြောင်းတာကို တားဆီးပါတယ် |
Encapsulation ဆိုတာ ဆက်စပ်နေတဲ့ ဒေတာနဲ့ အဲဒီ ဒေတာပေါ်မှာ အလုပ်လုပ်တဲ့ method တွေကို unit တစ်ခုတည်း (class တစ်ခု) ထဲ စုထုပ်တာ၊ attribute (object ရဲ့ ဒေတာကို သိမ်းတဲ့ variable) တွေကို private လုပ်ထားတာ၊ ပြီးတော့ တခြား code ကို public method တွေကနေတစ်ဆင့်ပဲ attribute တွေကို သုံးခွင့်ပေးတာ ဖြစ်ပါတယ်။ အဓိပ္ပာယ် အပြည့်အစုံမှာ ဒီ အပိုင်း သုံးပိုင်းလုံး ပါရပါမယ်။
Accessor Methods (Getters) (private attribute ရဲ့ တန်ဖိုးကို ပြန်ပေးတဲ့ method များ)
Accessor method က private instance variable (object တစ်ခုချင်းရဲ့ ကိုယ်ပိုင် variable) ရဲ့ တန်ဖိုးကို မပြောင်းဘဲ ပြန်ပေးပါတယ်။ Object ရဲ့ ဒေတာကို read-only access (ဖတ်ရုံပဲ ဖတ်ခွင့်) ပေးပါတယ်။
နာမည်ပေးပုံ: type အများစုအတွက် getAttributeName()၊ boolean (true ဒါမှမဟုတ် false တန်ဖိုးပဲ ယူတဲ့) attribute တွေအတွက် isAttributeName()။
public class Student {
private String name;
private int grade;
private boolean graduated;
// Accessor methods
public String getName() { return name; }
public int getGrade() { return grade; }
public boolean isGraduated() { return graduated; }
}
class Student():
# (constructor creating _name, _grade, _graduated not shown)
# Accessor methods
def get_name(self):
return self._name
def get_grade(self):
return self._grade
def is_graduated(self):
return self._graduated
Getter တွေက ရိုးရှင်းပါတယ်: တန်ဖိုးကို ပြန်ပေးရုံပါပဲ။ ဘာမှ မပြောင်းပါဘူး။
Mutator Methods (Setters) (private attribute ရဲ့ တန်ဖိုးကို ပြောင်းတဲ့ method များ)
Mutator method က private instance variable ရဲ့ တန်ဖိုးကို ပြောင်းပေးပါတယ်။ Controlled write access (ထိန်းချုပ်ထားတဲ့ ရေးခွင့်) ကို ပေးပါတယ်: များသောအားဖြင့် မှန်ကန်တဲ့ တန်ဖိုးတွေကိုပဲ လက်ခံအောင် validation ပါပါတယ်။
နာမည်ပေးပုံ: setAttributeName(newValue)၊ ဒါမှမဟုတ် restock()၊ enrol() လို လုပ်တဲ့ အလုပ်ကို ဖော်ပြတဲ့ verb (ကြိယာ) တစ်ခု။
public class Student {
private String name;
private int grade;
private boolean graduated;
// Constructor
public Student(String name, int grade) {
this.name = name;
this.grade = grade;
this.graduated = false;
}
// Mutator with validation
public void setGrade(int grade) {
if (grade >= 0 && grade <= 100) {
this.grade = grade;
}
}
// Mutator with logic
public void graduate() {
if (grade >= 50) {
this.graduated = true;
}
}
// Accessors
public String getName() { return name; }
public int getGrade() { return grade; }
public boolean isGraduated() { return graduated; }
}
class Student():
# Constructor
def __init__(self, name, grade):
self._name = name
self._grade = grade
self._graduated = False
# Mutator with validation
def set_grade(self, grade):
if grade >= 0 and grade <= 100:
self._grade = grade
# Mutator with logic
def graduate(self):
if self._grade >= 50:
self._graduated = True
# Accessors
def get_name(self):
return self._name
def get_grade(self):
return self._grade
def is_graduated(self):
return self._graduated
Attribute တိုင်းမှာ setter မလိုပါဘူး။ တချို့ attribute တွေက object ဖန်တီးပြီးနောက် read-only (ဖတ်ရုံပဲ ဖတ်လို့ရတဲ့) ဖြစ်သင့်ပါတယ်: ဥပမာ ကျောင်းသား တစ်ယောက်ရဲ့ နာမည် ဒါမှမဟုတ် ID က object ဖန်တီးပြီးရင် မပြောင်းသင့်ပါဘူး။ တကယ် ပြောင်းဖို့ လိုတဲ့ attribute တွေအတွက်ပဲ setter ပေးပါ။
Encapsulation ပုံစံ
Encapsulate လုပ်ထားတဲ့ class တွေအတွက် စံ ပုံစံ:
- Attribute တွေက
private: ဘယ်တော့မှpublicမဖြစ်ရပါ - Getter တွေက
public: ဖတ်ခွင့် ပေးပါတယ် - Setter တွေက
publicဖြစ်ပြီး validation ပါ: ထိန်းချုပ်ထားတဲ့ ရေးခွင့် ပေးပါတယ် - Constructor က attribute အားလုံးကို initialise (ပထမဆုံး တန်ဖိုး ထည့်) လုပ်ပါတယ်၊ လိုရင် validation ပါ ပါတယ်
public class Temperature {
private double celsius; // 1. private attribute
public Temperature(double celsius) {
if (celsius >= -273.15) {
this.celsius = celsius;
} else {
this.celsius = -273.15;
}
}
public double getCelsius() { // 2. public getter
return celsius;
}
public void setCelsius(double celsius) { // 3. public setter with validation
if (celsius >= -273.15) {
this.celsius = celsius;
}
}
public double toFahrenheit() { // public method using the data
return celsius * 9.0 / 5.0 + 32;
}
}
class Temperature():
def __init__(self, celsius): # 1. private attribute, set with validation
if celsius >= -273.15:
self._celsius = celsius
else:
self._celsius = -273.15
def get_celsius(self): # 2. public getter
return self._celsius
def set_celsius(self, celsius): # 3. public setter with validation
if celsius >= -273.15:
self._celsius = celsius
def to_fahrenheit(self): # public method using the data
return self._celsius * 9.0 / 5.0 + 32
Encapsulation မရှိရင် ဘာဖြစ်မလဲ
အတွင်းမှာ ရှိတဲ့ index (နေရာအမှတ်) က 0 နဲ့ capacity-1 ကြားမှာ အမြဲ ရှိနေရမယ့် CircularBuffer class တစ်ခုကို စဉ်းစားကြည့်ပါ (capacity ဆိုတာ buffer ထဲ ဆံ့နိုင်တဲ့ အများဆုံး အရေအတွက်ပါ)။ Encapsulation မရှိရင်:
// Dangerous: public fields
buffer.index = 9999; // way beyond capacity -- corrupts memory
buffer.index = -1; // invalid -- causes ArrayIndexOutOfBoundsException
# Dangerous: public attributes
buffer.index = 9999 # way beyond capacity - corrupts the buffer's state
buffer.index = -1 # invalid - causes an IndexError later
Encapsulation ရှိရင် class က သူ့ကိုယ်သူ ကာကွယ်ပါတယ်:
public void advanceIndex() {
index = (index + 1) % capacity; // always stays in range
}
def advance_index(self):
self._index = (self._index + 1) % self._capacity # always stays in range
index က private ဖြစ်လို့ အပြင်က ဘယ် code ကမှ index ထဲကို မမှန်တဲ့ တန်ဖိုး ထည့်လို့ မရပါဘူး။
အဆင့်ဆင့် ရှင်းပြထားတဲ့ ဥပမာများ
ဥပမာ 1: Encapsulate လုပ်ထားတဲ့ class တစ်ခုကို ဒီဇိုင်းဆွဲခြင်း
အခြေအနေ: Online ဆိုင် တစ်ဆိုင်အတွက် Product class တစ်ခု။ ကုန်ပစ္စည်း တစ်ခုစီမှာ နာမည်၊ ဈေးနှုန်းနဲ့ stock (လက်ကျန် ပစ္စည်း) အရေအတွက် ရှိပါတယ်။ ဈေးနှုန်းက အပေါင်းကိန်း ဖြစ်ရပါမယ်။ Stock က အနုတ် မဖြစ်ရပါဘူး။
public class Product {
private String name;
private double price;
private int stock;
public Product(String name, double price, int stock) {
this.name = name;
this.price = (price > 0) ? price : 0.01;
this.stock = (stock >= 0) ? stock : 0;
}
// Getters
public String getName() { return name; }
public double getPrice() { return price; }
public int getStock() { return stock; }
public boolean isInStock() { return stock > 0; }
// Setters with validation
public void setPrice(double price) {
if (price > 0) {
this.price = price;
}
}
// Business methods
public boolean sell(int quantity) {
if (quantity > 0 && quantity <= stock) {
stock = stock - quantity;
return true;
}
return false;
}
public void restock(int quantity) {
if (quantity > 0) {
stock = stock + quantity;
}
}
}
class Product():
def __init__(self, name, price, stock):
self._name = name
if price > 0:
self._price = price
else:
self._price = 0.01
if stock >= 0:
self._stock = stock
else:
self._stock = 0
# Getters
def get_name(self):
return self._name
def get_price(self):
return self._price
def get_stock(self):
return self._stock
def is_in_stock(self):
return self._stock > 0
# Setter with validation
def set_price(self, price):
if price > 0:
self._price = price
# Business methods
def sell(self, quantity):
if quantity > 0 and quantity <= self._stock:
self._stock = self._stock - quantity
return True
return False
def restock(self, quantity):
if quantity > 0:
self._stock = self._stock + quantity
Encapsulation က တားဆီးပေးတဲ့ အရာများ:
- ဈေးနှုန်းကို 0 ဒါမှမဟုတ် အနုတ်ကိန်း ထည့်ခြင်း
- Stock ကို အနုတ်ကိန်း ထည့်ခြင်း
- ရှိတာထက် ပစ္စည်း ပိုရောင်းခြင်း
- အနုတ် ပမာဏနဲ့ restock (stock ပြန်ဖြည့်) လုပ်ခြင်း
- ဖန်တီးပြီးနောက်
nameကို တိုက်ရိုက် ပြောင်းခြင်း (setter မပေးထားလို့ read-only ဖြစ်ပါတယ်)
ဥပမာ 2: Encapsulation မပါခင်နဲ့ ပါပြီးနောက်
Encapsulation မပါရင် (ပျက်နေတဲ့ ပုံစံ):
Product p = new Product();
p.price = -50.0; // invalid price
p.stock = -10; // impossible stock
// The object is now in an impossible state
p = Product() # imagine a version with public attributes and no validation
p.price = -50.0 # invalid price
p.stock = -10 # impossible stock
# The object is now in an impossible state
Encapsulation ပါရင် (စိတ်ချရတဲ့ ပုံစံ):
Product p = new Product("Widget", -50.0, -10);
// Constructor clamps: price becomes 0.01, stock becomes 0
System.out.println(p.getPrice()); // 0.01
System.out.println(p.getStock()); // 0
p.setPrice(-20.0); // rejected -- price stays 0.01
p.sell(5); // rejected -- not enough stock
// The object is always in a valid state
p = Product("Widget", -50.0, -10)
# Constructor clamps: price becomes 0.01, stock becomes 0
print(p.get_price()) # 0.01
print(p.get_stock()) # 0
p.set_price(-20.0) # rejected - price stays 0.01
p.sell(5) # rejected - not enough stock
# The object is always in a valid state
Quick Check (အမြန် စစ်ဆေးမေးခွန်း)
Q1. Encapsulation ဆိုတာ ဘာလဲ။
Q2. အောက်ပါတွေထဲက ဘယ်ဟာက encapsulation ရဲ့ အားသာချက် မဟုတ်သလဲ။
Q3. Accessor method က ဘာလုပ်သလဲ။
Q4. Product တစ်ခုရဲ့ ဈေးနှုန်းက 19.99 ပါ။ setPrice(-5) ကို ခေါ်လိုက်ရင် ဘာဖြစ်မလဲ။
Q5. Private attribute တိုင်းမှာ public setter ရှိသင့်သလား။
Spot the Error (အမှား ရှာခြင်း)
ဒီ class က compile ဖြစ်ပေမယ့် encapsulation ကို ချိုးဖောက်ထားပါတယ်။ အမှားပါတဲ့ line ကို ရွေးပါ၊ ပြီးရင် ပြင်နည်းကို ရွေးပါ။
မှန်ကန်တဲ့ ပြင်နည်းကို ရွေးပါ:
Fill in the Blanks (ကွက်လပ် ဖြည့်ခြင်း)
Encapsulate လုပ်ထားတဲ့ ဒီ class ရဲ့ ကွက်လပ်တွေကို ဖြည့်ပါ:
public class Student {
String name;
int grade;
public Student(String name, int grade) {
= name;
= grade;
}
// Accessor method
public String () {
return name;
}
// Mutator method with validation
public void setGrade(int grade) {
if (grade >= 0 && grade <= 100) {
= grade;
}
}
} Predict the Output (output ကို ကြိုခန့်မှန်းခြင်း)
ဥပမာ 1 က Product class ကို သုံးထားပါတယ်:
Product p = new Product("Widget", 9.99, -5);
p.sell(3);
System.out.println(p.getStock());ဘာ print ထွက်မလဲ။
ဘာ print ထွက်မလဲ။
Product p = new Product("Gadget", 29.99, 10);
p.sell(3);
p.sell(5);
p.sell(5);
System.out.println(p.getStock());ဘာ print ထွက်မလဲ။
Practice Exercises (လေ့ကျင့်ခန်းများ)
[2 marks] စတာတွေက အပိုင်း တစ်ခုချင်းစီအတွက် ရနိုင်တဲ့ အမှတ်ပါ။ IB Computer Science (နိုင်ငံတကာ ကျောင်းတွေမှာ သင်တဲ့ ကွန်ပျူတာသိပ္ပံ သင်ရိုး) စာမေးပွဲ မေးခွန်းတွေမှာ အမှတ်ကို ဒီလို ပြလေ့ ရှိပါတယ်။
Core (အခြေခံ အဆင့်)
-
ဘာကြောင့်လဲ Explain (ရှင်းပြပါ): ကျောင်းသား တစ်ယောက်က သူ့ Person class ထဲမှာ
public int age;လို့ ရေးထားပါတယ်။ ဒီလို ရေးတာကြောင့် ဖြစ်လာတဲ့ ပြဿနာ နှစ်ခုနဲ့ encapsulation က ပြဿနာ တစ်ခုစီကို ဘယ်လို ဖြေရှင်းပေးလဲဆိုတာကို Explain လုပ်ပါ။ - Encapsulate လုပ်ထားတဲ့ class တစ်ခု ရေးခြင်း:
memberName(String)၊yearJoined(int)၊tier(String) နဲ့isActive(boolean) field တွေပါတဲ့ encapsulate လုပ်ထားတဲ့ClubMembershipclass တစ်ခုကို Construct (ကိုယ်တိုင် တည်ဆောက်ပါ) လုပ်ပါ။ ဒီ class မှာmemberName၊yearJoinedနဲ့isActiveအတွက် ရိုးရိုး setter တွေ ရှိပြီးသားပါ။- (a) Encapsulate လုပ်ထားတဲ့ class အတွက် မှန်ကန်တဲ့ access modifier ကို သုံးပြီး field declaration (ကြေညာခြင်း) လေးခုကို Construct လုပ်ပါ။ [2 marks]
- (b) Field နာမည်တွေနဲ့ နာမည်တူတဲ့ parameter (method ကို ပေးလိုက်တဲ့ တန်ဖိုးကို လက်ခံတဲ့ variable) လေးခုကို ယူပြီး တစ်ခုစီကို သက်ဆိုင်ရာ setter ဆီ ပေးပို့တဲ့ (ဥပမာ
setTier(tier);) parameterised constructor (parameter တွေ ပါတဲ့ constructor) တစ်ခုကို Construct လုပ်ပါ။ ဒါမှ object ဖန်တီးတဲ့အခါမှာလည်း setter ရဲ့ စစ်ဆေးချက် run ပါမယ်။ [3 marks] - (c)
tierအတွက် accessor တစ်ခုကို Construct လုပ်ပါ။ [1 mark] - (d)
"Bronze"၊"Silver"ဒါမှမဟုတ်"Gold"တန်ဖိုးတွေကိုပဲ ခွင့်ပြုတဲ့tierအတွက် mutator တစ်ခုကို Construct လုပ်ပါ။ မမှန်တဲ့ တန်ဖိုး ပေးရင် field ကို မပြောင်းဘဲ ထားရပါမယ်။ [3 marks]
- Read-only attribute များ:
nameနဲ့studentIDမှာ getter ရှိပေမယ့် setter မရှိတဲ့ (object ဖန်တီးပြီးနောက် read-only ဖြစ်တဲ့)၊gradeမှာတော့ getter ရော validation ပါတဲ့ setter (0-100) ပါ ရှိတဲ့Studentclass တစ်ခုကို ဖန်တီးပါ။
Extension (တိုးချဲ့ အဆင့်)
- Encapsulation စစ်ဆေးခြင်း: အောက်က class မှာ encapsulation ချိုးဖောက်မှု သုံးခု ရှိပါတယ်။ အားလုံးကို ရှာပြီး ပြင်ပါ:
public class Ticket { public String event; public double price; private boolean used; public void useTicket() { used = true; } public void setPrice(double p) { price = p; } } - Design စိန်ခေါ်မှု:
Passwordclass က hash လုပ်ထားတဲ့ (မူလ စာသားကို ပြန်မဖော်နိုင်အောင် ပြောင်းထားတဲ့) password ကို သိမ်းပါတယ်။ Password ကို သတ်မှတ်လို့ ရပေမယ့် (အနည်းဆုံး အရှည်ကို validation လုပ်ပြီး) ဘယ်တော့မှ ပြန်ဖတ်လို့ မရအောင် (တကယ့် password အတွက် getter မရှိအောင်) class ကို Design (အစီအစဉ် ဒါမှမဟုတ် model တစ်ခု ရေးဆွဲပါ) လုပ်ပါ။ true/false ပြန်ပေးတဲ့checkPassword(String attempt)method တစ်ခု ထည့်ပေးပါ။
Challenge (စိန်ခေါ်မှု အဆင့်)
- Encapsulate လုပ်ထားတဲ့ စနစ် အပြည့်အစုံ:
Noticeobject တွေရဲ့ array (အရွယ်အစား ပုံသေ၊ အမျိုးအစားတူ ဒေတာစု) တစ်ခုကို စီမံတဲ့ ကျောင်း ကြေညာဘုတ် (noticeboard) အတွက်Noticeboardclass တစ်ခုကို Design လုပ်ပါ။ ကြေညာချက် (notice) တစ်ခုစီမှာ code တစ်ခု ("N1"လို)၊ ခေါင်းစဉ် တစ်ခုနဲ့ ဘုတ်ပေါ်မှာ ကျန်တဲ့ ရက်အရေအတွက် ရှိပါတယ်။ Noticeboard က သူ့ notice တွေကို encapsulate လုပ်ထားရပါမယ် (private array)။ ပြီးတော့ ဒီ အလုပ်တွေအတွက် method တွေ ပေးရပါမယ်: notice တစ်ခု ထည့်ခြင်း၊ code နဲ့ notice တစ်ခုကို ဖယ်ခြင်း၊ notice တစ်ခုရဲ့ ရက်ကို 1 ကနေ 7 ရက်အထိ တိုးခြင်း၊ ကျောင်းရက် တစ်ရက် ပြီးတိုင်း notice အားလုံးရဲ့ ကျန်ရက်ကို တစ်ရက်စီ လျှော့ခြင်း နဲ့ ပြနေဆဲ notice တွေ (အနည်းဆုံး တစ်ရက် ကျန်သေးတဲ့ notice တွေ) ကို ရေတွက်ခြင်း။ အပြင်က ဘယ် code ကမှ array ကို တိုက်ရိုက် သုံးလို့ မရရပါဘူး၊ Noticeboard method တွေကို မဖြတ်ဘဲ notice တစ်ခုကို ပြောင်းလို့လည်း မရရပါဘူး။
ဆက်စပ် ခေါင်းစဉ်များ
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: The
thisKeyword:thisက getter/setter ပုံစံကို ရေးလို့ရအောင် လုပ်ပေးပါတယ် - အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Constructors: constructor တွေက private attribute တွေကို initialise လုပ်ပါတယ်
- နောက်ထပ် လေ့လာမယ့် ခေါင်းစဉ်: Access Modifiers။
private,public,protectedအကြောင်း ပိုနက်နက် လေ့လာပါမယ် - ဆက်စပ် ခေါင်းစဉ်: UML Class Diagrams (class တစ်ခုကို အကွက် သုံးကွက်နဲ့ ပြတဲ့ ပုံ)။
-က private ကို၊+က public ကို ဆိုလိုပါတယ် - ရှေ့ဆက် ခေါင်းစဉ်: Inheritance (parent class ကနေ အမွေဆက်ခံခြင်း)။ Encapsulate လုပ်ထားတဲ့ attribute တွေကို child class တွေက အမွေဆက်ခံပေမယ့် getter တွေကနေတစ်ဆင့် သုံးရပါတယ်