Aggregation (သီးခြား ရှိနေနိုင်တဲ့ has-a ဆက်နွယ်မှု)
B3.2.4 (HL): Explain the role of aggregation (has-a relationship with independent existence) in class relationships.
မြန်မာလို: class (object တွေ ဖန်တီးဖို့ ပုံစံခွက်) တွေကြား ဆက်နွယ်မှုတွေမှာ aggregation (သီးခြား ရှိနေနိုင်တဲ့ has-a ဆက်နွယ်မှု) ရဲ့ အခန်းကဏ္ဍကို explain (ရှင်းပြ) နိုင်ရပါမယ်။ Aggregation မှာ အစိတ်အပိုင်း object က တစ်ခုလုံး object မရှိဘဲ သီးခြား ဆက်ရှိနေနိုင်ပါတယ်။
ဒီစာမျက်နှာက HL အတွက်ပဲ ဖြစ်ပါတယ်။ SL (Standard Level) နဲ့ HL (Higher Level) ဆိုတာ IB Computer Science (နိုင်ငံတကာ ကျောင်းတွေမှာ သင်တဲ့ ကွန်ပျူတာသိပ္ပံ သင်ရိုး) သင်တန်းရဲ့ အဆင့်နှစ်ဆင့်ဖြစ်ပြီး HL အပိုင်းတွေက ပိုနက်နက်ရှိုင်းရှိုင်း လေ့လာရတဲ့ အပိုင်းတွေပါ။
အဓိက အယူအဆများ
Aggregation ဆိုတာ ဘာလဲ
Aggregation ဆိုတာ object (class တစ်ခုကနေ ဖန်တီးထားတဲ့ instance) တစ်ခုက နောက်ထပ် object တစ်ခုကို attribute (object ရဲ့ ဒေတာကို သိမ်းတဲ့ variable) တစ်ခုအဖြစ် ပါဝင်ထားတဲ့ ဆက်နွယ်မှုပါ။ ဒါက “has-a” (object တစ်ခုထဲမှာ နောက် object တစ်ခု ပါဝင်တဲ့) ဆက်နွယ်မှုပါ: MovingVan မှာ Box object တွေ ရှိတယ်၊ School မှာ Student object တွေ ရှိတယ်၊ Car မှာ Engine တစ်ခု ရှိတယ်။
အခြား object ကို ပါဝင်ထားတဲ့ object (“whole”၊ တစ်ခုလုံး) က သူ့ထဲမှာ ပါတဲ့ object (“part”၊ အစိတ်အပိုင်း) ရဲ့ reference (object ရှိရာ memory နေရာကို ညွှန်းတဲ့ တန်ဖိုး) ကို သိမ်းထားပြီး အဲဒီ object ရဲ့ method (သီးခြား အလုပ်တစ်ခု လုပ်ပေးတဲ့ code အပိုင်း) တွေကို ခေါ်သုံးနိုင်ပါတယ်။ ဒီနည်းနဲ့ ပိုရိုးရှင်းတဲ့ အစိတ်အပိုင်းတွေကနေ ရှုပ်ထွေးတဲ့ စနစ်တွေကို တည်ဆောက်နိုင်ပါတယ်။
public class Address {
private String street;
private String city;
private String country;
public Address(String street, String city, String country) {
this.street = street;
this.city = city;
this.country = country;
}
public String getCity() { return city; }
public String getCountry() { return country; }
}
public class Student {
private String name;
private Address homeAddress; // aggregation: Student HAS-A Address
public Student(String name, Address homeAddress) {
this.name = name;
this.homeAddress = homeAddress;
}
public String getName() { return name; }
// Delegation: calling a method on the contained object
public String getCity() {
return homeAddress.getCity();
}
}
class Address():
def __init__(self, street, city, country):
self._street = street
self._city = city
self._country = country
def get_city(self):
return self._city
def get_country(self):
return self._country
class Student():
def __init__(self, name, home_address):
self._name = name
self._home_address = home_address # aggregation: Student HAS-A Address
def get_name(self):
return self._name
# Delegation: calling a method on the contained object
def get_city(self):
return self._home_address.get_city()
Address addr = new Address("123 Main St", "Bangkok", "Thailand");
Student s = new Student("Alice", addr);
System.out.println(s.getName() + " lives in " + s.getCity());
addr = Address("123 Main St", "Bangkok", "Thailand")
s = Student("Alice", addr)
print(s.get_name(), "lives in", s.get_city())
Output (program က ထုတ်ပြတဲ့ ရလဒ်):
Alice lives in Bangkok
Student object က address တွေ အတွင်းပိုင်းမှာ ဘယ်လို အလုပ်လုပ်လဲ မသိပါဘူး: homeAddress.getCity() ကိုပဲ ခေါ်လိုက်တာပါ။ ဒါကို delegation (အလုပ်ကို တခြား object ဆီ လွှဲပေးခြင်း) လို့ ခေါ်ပါတယ်: တာဝန်ကို သူ့ထဲမှာ ပါတဲ့ object ဆီ လွှဲပေးလိုက်တာပါ။
Aggregation နဲ့ Inheritance
Class တွေ အချင်းချင်း ဆက်နွယ်တဲ့ အခြေခံ နည်းလမ်း နှစ်မျိုးက aggregation နဲ့ inheritance (parent class ကနေ အမွေဆက်ခံခြင်း) ပါ။ မှားတဲ့ တစ်ခုကို သုံးမိရင် design ပြဿနာတွေ ဖြစ်ပါတယ်။
| Aggregation (has-a) | Inheritance (is-a) | |
|---|---|---|
| ဆက်နွယ်မှု | Object တစ်ခုက နောက်တစ်ခုကို ပါဝင်ထားတယ် | Class တစ်ခုက နောက်တစ်ခုကို extends လုပ်တယ် (ဆက်ချဲ့တယ်) |
| ဥပမာ | Car မှာ Engine ရှိတယ် | Dog က Animal အမျိုးအစား တစ်ခု ဖြစ်တယ် |
| Code | private Engine engine; | class Dog extends Animal |
| Coupling (class တွေ အချင်းချင်း မှီခိုမှု) | Loose (မှီခိုမှု နည်း): အစိတ်အပိုင်းတွေက သီးခြား ရှိနိုင်တယ် | Tight (မှီခိုမှု များ): child က parent ပေါ် မှီခိုတယ် |
| Polymorphism (ပုံစံ အမျိုးမျိုး ယူနိုင်ခြင်း) | မရပါ | ရပါတယ် |
| ပြောင်းလွယ်မှု | Runtime (program run နေစဉ်) မှာ အစိတ်အပိုင်းတွေကို လဲလို့ရတယ် | Compile time (compile လုပ်ချိန်) မှာ ပုံသေ ဖြစ်သွားတယ် |
Aggregation နဲ့ inheritance ထဲက ဘယ်ဟာ သုံးမလဲ ဆုံးဖြတ်ဖို့ “A က B ရဲ့ အမျိုးအစား တစ်ခုလား” လို့ မေးပါ။ ဟုတ်ရင် inheritance ကို သုံးပါ (Dog IS-A Animal)။ မဟုတ်ရင် “A ထဲမှာ B ပါသလား” လို့ ထပ်မေးပါ။ ပါရင် aggregation ကို သုံးပါ (Car HAS-A Engine)။ Code ကို ပြန်သုံးချင်လို့ သက်သက်နဲ့ inheritance ကို ဘယ်တော့မှ မသုံးပါနဲ့: အဲဒီအစား aggregation ကို သုံးပါ။
Arrays of Objects (object တွေကို သိမ်းထားတဲ့ array များ)
Aggregation ရဲ့ အသုံးများတဲ့ ပုံစံ တစ်ခုက object တွေရဲ့ array (array: အရွယ်အစား ပုံသေ၊ အမျိုးအစားတူ ဒေတာစု) ကို စီမံတဲ့ class ပါ။ Method ပုံစံတွေ (filter: condition နဲ့ ကိုက်တာတွေကိုပဲ ရွေးထုတ်ခြင်း၊ accumulate: တန်ဖိုးတွေကို တဖြည်းဖြည်း စုပေါင်းခြင်း၊ sort: အစဉ်တကျ စီခြင်း) ကို အသုံးချတာ ဒီနေရာမှာပါ။
အောက်က ဥပမာက အိမ်ပြောင်းနေတဲ့ မိသားစု တစ်စုအတွက် Box object တွေကို တင်ဆောင်တဲ့ MovingVan (ပစ္စည်းသယ်ကား) ပါ။ Box တစ်ခုစီက သူ့ကိုယ်ပိုင် label (box ပေါ်က စာကပ်)၊ room (ဘယ်အခန်းအတွက်လဲ) နဲ့ weight (အလေးချိန်) ကို ကိုယ်တိုင် ထိန်းသိမ်းပါတယ်:
public class Box {
private String label;
private String room;
private int weightKg;
public Box(String label, String room) {
this.label = label;
this.room = room;
this.weightKg = 0; // a new box starts empty
}
public String getLabel() { return label; }
public String getRoom() { return room; }
public int getWeightKg() { return weightKg; }
public void pack(int itemKg) {
if (itemKg > 0) {
weightKg = weightKg + itemKg;
}
}
public boolean isHeavy() {
return weightKg > 15; // two people should lift it
}
}
class Box():
def __init__(self, label, room):
self._label = label
self._room = room
self._weight_kg = 0 # a new box starts empty
def get_label(self):
return self._label
def get_room(self):
return self._room
def get_weight_kg(self):
return self._weight_kg
def pack(self, item_kg):
if item_kg > 0:
self._weight_kg = self._weight_kg + item_kg
def is_heavy(self):
return self._weight_kg > 15 # two people should lift it
MovingVan က သူ့ box တွေကို array ထဲမှာ သိမ်းပြီး box တွေရဲ့ getter (private attribute ရဲ့ တန်ဖိုးကို ပြန်ပေးတဲ့ method) တွေကို သုံးပါတယ်။ Box တွေကို ကား မရောက်ခင်ကတည်းက ထုပ်ပိုးထားပြီး အိမ်သစ်ရောက်မှ ပြန်ဖြည်ပါတယ်။ ဒါကြောင့် box တွေက ကားနဲ့ မဆိုင်ဘဲ သီးခြား ရှိနေပါတယ်:
public class MovingVan {
private String name;
private Box[] boxes;
private int boxCount;
public MovingVan(String name, int capacity) {
this.name = name;
this.boxes = new Box[capacity];
this.boxCount = 0;
}
public void loadBox(Box box) {
if (boxCount < boxes.length) {
boxes[boxCount] = box;
boxCount++;
}
}
// Filter pattern: find boxes matching a condition
public void displayHeavy() {
for (int i = 0; i < boxCount; i++) {
if (boxes[i] != null && boxes[i].isHeavy()) {
System.out.println(boxes[i].getLabel());
}
}
}
// Accumulate pattern: count items matching a condition
public int countForRoom(String room) {
int count = 0;
for (int i = 0; i < boxCount; i++) {
if (boxes[i] != null && boxes[i].getRoom().equals(room)) {
count++;
}
}
return count;
}
}
class MovingVan():
def __init__(self, name, capacity):
self._name = name
self._boxes = [] # a Python list starts empty and grows,
self._capacity = capacity # so len() does the job of box_count
def load_box(self, box):
if len(self._boxes) < self._capacity:
self._boxes.append(box)
# Filter pattern: find boxes matching a condition
def display_heavy(self):
for i in range(len(self._boxes)):
if self._boxes[i] != None and self._boxes[i].is_heavy() == True:
print(self._boxes[i].get_label())
# Accumulate pattern: count items matching a condition
def count_for_room(self, room):
count = 0
for i in range(len(self._boxes)):
if self._boxes[i] != None and self._boxes[i].get_room() == room:
count = count + 1
return count
Array ထဲက element (အစုထဲက အချက်) တွေပေါ်မှာ method ကို မခေါ်ခင်
null(ဘာ object ကိုမှ မညွှန်းတဲ့ တန်ဖိုး) ဟုတ်မဟုတ် အမြဲ စစ်ပါ။boxCountနဲ့ အရေအတွက်ကို မှတ်ထားရင်တောင် ကြိုတင် ကာကွယ်တဲ့ null စစ်ချက်တွေက element တွေကို ဖယ်ထုတ်လိုက်တဲ့အခါ ဒါမှမဟုတ် array ထဲမှာ အကွက် တချို့ကိုပဲ ဖြည့်ထားတဲ့အခါ ဖြစ်တတ်တဲ့ bug (code ထဲက အမှား) တွေကနေ ကာကွယ်ပေးပါတယ်။
Delegation (အလုပ်ကို တခြား object ဆီ လွှဲပေးခြင်း)
“Whole” object က “part” ဆီက အချက်အလက် လိုတဲ့အခါ ဒေတာကို တိုက်ရိုက် မယူဘဲ သူ့ထဲမှာ ပါတဲ့ object ရဲ့ method ကို ခေါ်ပြီး delegate လုပ်ပါတယ် (တာဝန် လွှဲပေးပါတယ်):
public class Car {
private Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
// Delegation: Car asks Engine for its horsepower
public int getHorsepower() {
return engine.getHorsepower();
}
// Delegation with logic
public boolean isPowerful() {
return engine.getHorsepower() > 200;
}
}
class Car():
def __init__(self, engine):
self._engine = engine
# Delegation: Car asks Engine for its horsepower
def get_horsepower(self):
return self._engine.get_horsepower()
# Delegation with logic
def is_powerful(self):
return self._engine.get_horsepower() > 200
Car က horsepower (engine ရဲ့ အားကို တိုင်းတဲ့ ယူနစ်) ကို ကိုယ်တိုင် မသိမ်းပါဘူး: သူ့ Engine ကို မေးပါတယ်။ Engine ကို တစ်ခြား engine နဲ့ လဲလိုက်ရင် car က horsepower အသစ်ကို အလိုအလျောက် ပြန်ပြောပါတယ်။ ဒီနည်းက class တစ်ခုစီကို သူ့ကိုယ်ပိုင် ဒေတာအတွက် တာဝန်ယူစေပါတယ်။ Engine ကို Car ရဲ့ အပြင်မှာ ဖန်တီးပြီး Car ရဲ့ constructor (object ဖန်တီးချိန် attribute တွေကို စတင် သတ်မှတ်ပေးတဲ့ method) ကို ပေးလိုက်တာပါ။ ဒါကြောင့်ပဲ ဒါက aggregation ဖြစ်ပါတယ်: engine က car မရှိဘဲ ရှိနေနိုင်ပါတယ်။
Nested Object Access (object အဆင့်ဆင့်ထဲက ဒေတာကို ယူခြင်း)
တစ်ခါတလေ အဆင့် အများကြီး နက်တဲ့ နေရာက ဒေတာကို ယူဖို့ လိုပါတယ်။ အဆင့်တိုင်းမှာ ပြန်ရလာတဲ့ object ပေါ်က method ကို ခေါ်ပါတယ်:
// van.getBoxes()[i].getRoom()
// ↑ get the array
// ↑ get one box
// ↑ get that box's room
# van.get_boxes()[i].get_room()
# ↑ get the list
# ↑ get one box
# ↑ get that box's room
Code ထဲက မှတ်ချက်တွေက get the array (array ကို ယူ၊ Python မှာ get the list: list ကို ယူ)၊ get one box (box တစ်ခုကို ယူ)၊ get that box’s room (အဲဒီ box ရဲ့ room ကို ယူ) လို့ ဆိုလိုပါတယ်။
ဒီပုံစံမှာ getter ခေါ်မှုတွေကို ဆက်တိုက် ချိတ်ပြီး container (တခြား object တွေကို သိမ်းထားတဲ့ object) ကနေ သူ့အစိတ်အပိုင်းတွေဆီ၊ ပြီးတော့ အစိတ်အပိုင်းတွေရဲ့ attribute တွေဆီ ဆင်းသွားပါတယ်။ ဒီ ခေါ်မှု ကွင်းဆက်က အပေါ်က Arrays of Objects အပိုင်းက MovingVan နဲ့ Box class တွေကို သုံးထားပြီး MovingVan မှာ box array ကို ပြန်ပေးတဲ့ getBoxes() getter လည်း ရှိတယ်လို့ ယူဆထားပါတယ်။
အဆင့်ဆင့် ရှင်းပြထားတဲ့ ဥပမာများ
ဥပမာ 1: Aggregation ကို သုံးပြီး design ဆွဲခြင်း
အခြေအနေ: Gym (အားကစားရုံ) မှာ member (အသင်းဝင်) တွေ ရှိပါတယ်။ Member တစ်ယောက်စီမှာ နာမည်နဲ့ membership type (အသင်းဝင် အမျိုးအစား) ရှိပါတယ်။ Gym က premium (အဆင့်မြင့်) member တွေကို ရေတွက်ဖို့နဲ့ နာမည်နဲ့ member ကို ရှာဖို့ လိုပါတယ်။
UML (class တွေကို ပုံနဲ့ ပြတဲ့ စံ ရေးဆွဲနည်း):
classDiagram
class Gym {
-name : String
-members : Member[]
-memberCount : int
+Gym(String, int)
+addMember(Member) void
+countPremium() int
+findByName(String) Member
}
class Member {
-name : String
-type : String
+Member(String, String)
+getName() String
+getType() String
+isPremium() boolean
}
Gym o-- Member
Java:
public class Member {
private String name;
private String type;
public Member(String name, String type) {
this.name = name;
this.type = type;
}
public String getName() { return name; }
public String getType() { return type; }
public boolean isPremium() { return type.equals("premium"); }
}
public class Gym {
private String name;
private Member[] members;
private int memberCount;
public Gym(String name, int capacity) {
this.name = name;
this.members = new Member[capacity];
this.memberCount = 0;
}
public void addMember(Member m) {
if (memberCount < members.length) {
members[memberCount] = m;
memberCount++;
}
}
// Accumulate pattern
public int countPremium() {
int count = 0;
for (int i = 0; i < memberCount; i++) {
if (members[i] != null && members[i].isPremium()) {
count++;
}
}
return count;
}
// Find-by-attribute pattern
public Member findByName(String name) {
for (int i = 0; i < memberCount; i++) {
if (members[i] != null && members[i].getName().equals(name)) {
return members[i];
}
}
return null; // not found
}
}
class Member():
def __init__(self, name, member_type): # "type" is a Python built-in,
self._name = name # so the parameter gets a safer name
self._type = member_type
def get_name(self):
return self._name
def get_type(self):
return self._type
def is_premium(self):
return self._type == "premium"
class Gym():
def __init__(self, name, capacity):
self._name = name
self._members = [] # grows with append - len() replaces memberCount
self._capacity = capacity
def add_member(self, m):
if len(self._members) < self._capacity:
self._members.append(m)
# Accumulate pattern
def count_premium(self):
count = 0
for i in range(len(self._members)):
if self._members[i] != None and self._members[i].is_premium():
count = count + 1
return count
# Find-by-attribute pattern
def find_by_name(self, name):
for i in range(len(self._members)):
if self._members[i] != None and self._members[i].get_name() == name:
return self._members[i]
return None # not found
ဥပမာ 2: Object Array ပေါ်မှာ Selection Sort (အငယ်ဆုံးကို ရှာပြီး နေရာချ စီခြင်း)
Member တွေကို နာမည်အလိုက် အက္ခရာစဉ် ascending order (ငယ်ရာကနေ ကြီးရာ) အတိုင်း စီပါ:
public void sortByName() {
for (int i = 0; i < memberCount - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < memberCount; j++) {
if (members[j].getName().compareTo(members[minIndex].getName()) < 0) {
minIndex = j;
}
}
// Swap entire objects
Member temp = members[i];
members[i] = members[minIndex];
members[minIndex] = temp;
}
}
def sort_by_name(self):
for i in range(len(self._members) - 1):
min_index = i
for j in range(i + 1, len(self._members)):
# Python compares strings alphabetically with < directly -
# no compareTo needed
if self._members[j].get_name() < self._members[min_index].get_name():
min_index = j
# Swap entire objects
temp = self._members[i]
self._members[i] = self._members[min_index]
self._members[min_index] = temp
Object တွေကို String (စာသား) attribute တစ်ခုနဲ့ စီတဲ့အခါ
<ဒါမှမဟုတ်>အစား.compareTo()ကို သုံးပါ။ ပထမ string က ဒုတိယ string ထက် အက္ခရာစဉ်အရ အရင်လာရင် negative number (အနုတ်ကိန်း) ကို ပြန်ပေးပါတယ်၊ နှစ်ခု တူရင် 0 ကို ပြန်ပေးပါတယ်၊ နောက်မှလာရင် positive number (အပေါင်းကိန်း) ကို ပြန်ပေးပါတယ်။ (Python မှာတော့<နဲ့>က string တွေကို အက္ခရာစဉ်အတိုင်း နှိုင်းယှဉ်လို့ အဲဒါတွေကို တိုက်ရိုက် သုံးပါတယ်။)
Quick Check (အမြန် စစ်ဆေးမေးခွန်း)
Q1. Aggregation က ဘယ်လို ဆက်နွယ်မှု အမျိုးအစားလဲ။
Q2. OOP (object တွေကို အခြေခံပြီး program ရေးနည်း) မှာ delegation ဆိုတာ ဘာလဲ။
Q3. Car ထဲမှာ Engine တစ်ခု ပါပါတယ်။ ဒါက aggregation ဖြစ်သင့်သလား၊ inheritance ဖြစ်သင့်သလား။
Q4. Charlie က array ထဲမှာ မရှိရင် findByName("Charlie") က ဘာကို return (ရလဒ်အဖြစ် ပြန်ပေး) လုပ်သလဲ။
Trace Exercise (code ကို တစ်ဆင့်ချင်း လိုက်ကြည့်ခြင်း)
Gym class ရဲ့ method တွေကို trace (တစ်ဆင့်ချင်း လိုက်ကြည့်ပြီး မှတ်) လုပ်ပါ။ Gym တစ်ခုမှာ member 3 ယောက် ရှိပါတယ်: Alice (premium)၊ Bob (basic)၊ Charlie (premium)။ ရလဒ်တွေကို code ထဲက တန်ဖိုးအတိုင်း English လို ရိုက်ထည့်ပါ။
Trace: Aggregation method များ
Gym g = new Gym("FitLife", 10);
g.addMember(new Member("Alice", "premium"));
g.addMember(new Member("Bob", "basic"));
g.addMember(new Member("Charlie", "premium"));| Method ခေါ်မှု | ရလဒ် |
|---|---|
g.countPremium() | |
g.findByName("Bob").getType() | |
g.findByName("Dave") |
Spot the Error (အမှား ရှာခြင်း)
MovingVan class ထဲက ဒီ method က NullPointerException (null reference ကို သုံးမိလို့ ဖြစ်တဲ့ error) နဲ့ crash (program ရုတ်တရက် ပျက်ပြီး ရပ်သွားခြင်း) ဖြစ်ပါတယ်။ အမှားပါတဲ့ line ကို ရွေးပါ၊ ပြီးရင် ပြင်နည်းကို ရွေးပါ။
1public void printAllLabels() {2 for (int i = 0; i < boxes.length; i++) {3 System.out.println(boxes[i].getLabel());4 }5}မှန်ကန်တဲ့ ပြင်နည်းကို ရွေးပါ:
Predict the Output (output ကို ကြိုခန့်မှန်းခြင်း)
Member တွေက Alice (premium)၊ Bob (basic)၊ Charlie (premium) ဖြစ်တဲ့ gym အတွက် countPremium() က ဘာကို return လုပ်သလဲ။
Practice Exercises (လေ့ကျင့်ခန်းများ)
Core (အခြေခံ အဆင့်)
-
Class နှစ်ခုကို design ဆွဲပါ:
Courseclass (name၊ teacher၊ maxStudents) တစ်ခုနဲ့ Course array တစ်ခုကို စီမံတဲ့Schoolclass တစ်ခုကို ဖန်တီးပါ။addCourse()၊findCourse(String name)နဲ့countAvailable()(စာရင်းသွင်းထားတဲ့ ကျောင်းသား အရေအတွက်က maxStudents ထက် နည်းသေးတဲ့ course တွေ) ကို ရေးပါ။ - Aggregation ကို ခွဲခြားခြင်း: အတွဲ တစ်တွဲစီအတွက် ဆက်နွယ်မှုက aggregation (has-a) လား၊ inheritance (is-a) လား State (ဖော်ပြပါ):
- (a) Playlist နဲ့ Song
- (b) ElectricCar နဲ့ Car
- (c) Hospital နဲ့ Doctor
- (d) Rectangle နဲ့ Shape
- ဖတ်ပြီး trace လုပ်ပါ: ဒီစာမျက်နှာက MovingVan နဲ့ Box class တွေကို သုံးပြီး box 3 ခုကို တင်၊ အဲဒီထဲက box တစ်ခုထဲကို ပစ္စည်း တစ်ခု ထပ်ထုပ်၊ ပြီးရင်
countForRoom()ကို ခေါ်တဲ့အခါ ဘာဖြစ်လဲဆိုတာကို trace လုပ်ပါ။
Extension (တိုးချဲ့ အဆင့်)
-
Selection sort: product တွေကို ဈေးနှုန်းအလိုက် descending order (ကြီးရာကနေ ငယ်ရာ) နဲ့ (ဈေးအကြီးဆုံး အရင်) စီပေးတဲ့
sortByPrice(Product[] products, int count)method ကို ထည့်ပါ။ Selection sort နဲ့ getter method တွေကို သုံးပါ။ -
Nested access:
DepartmentမှာEmployeeobject တွေရဲ့ array တစ်ခု ရှိပါတယ်။Employeeတစ်ယောက်စီမှာgetBase()နဲ့getBonus()method တွေ ပါတဲ့Salaryobject တစ်ခု ရှိပါတယ်။ ဝန်ထမ်း အားလုံးအတွက်base + bonusကို ပေါင်းပေးတဲ့totalPayroll()method ကိုDepartmentထဲမှာ ရေးပါ။
Challenge (စိန်ခေါ်မှု အဆင့်)
- စနစ် အပြည့်အစုံ:
Roomနဲ့Guestclass တွေ ပါတဲ့Hotelစနစ်တစ်ခုကို design ဆွဲပြီး ရေးပါ။ Hotel က room တွေကို စီမံပါတယ်။ Room တစ်ခုစီမှာ နံပါတ်၊ type (“single”/”double”)၊ ဈေးနှုန်းနဲ့ ရှိချင်မှ ရှိမယ့် Guest တစ်ယောက် ပါပါတယ်။ ဒါတွေကို ရေးပါ: check-in (guest ကို room ထဲ ထည့်ခြင်း)၊ check-out (guest ကို ဖယ်ခြင်း)၊ type အလိုက် လွတ်နေတဲ့ room တွေကို ရှာခြင်း၊ လူတည်းနေတဲ့ room တွေကနေ ရတဲ့ စုစုပေါင်း ဝင်ငွေကို တွက်ခြင်း။
ဆက်စပ် ခေါင်းစဉ်များ
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Classes and Objects (class နဲ့ object များ): object တွေကို ဖန်တီးပြီး သုံးခြင်း
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: UML Class Diagrams (class တစ်ခုကို အကွက် သုံးကွက်နဲ့ ပြတဲ့ ပုံများ): has-a ကို ပြတဲ့ diamond (◇) သင်္ကေတ
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Object References (object ကို ညွှန်းတဲ့ reference များ): null စစ်ချက်တွေ၊ reference တွေ အလုပ်လုပ်ပုံ
- နောက်ထပ် လေ့လာမယ့် ခေါင်းစဉ်: Inheritance (parent class ကနေ အမွေဆက်ခံခြင်း): နောက်ထပ် အခြေခံ ဆက်နွယ်မှု (is-a)
- နောက်ထပ် လေ့လာမယ့် ခေါင်းစဉ်: OOP Exam Patterns (စာမေးပွဲမှာ ပါတတ်တဲ့ OOP method ပုံစံများ)။ ဒီမှာ သုံးထားတဲ့ filter၊ accumulate နဲ့ sort ပုံစံတွေက စာမေးပွဲအတွက် မဖြစ်မနေ သိထားရမယ့် ပုံစံတွေပါ