Interfaces (class တစ်ခု implement လုပ်ရမယ့် method စာရင်းများ)
B3.2 (HL): Use interfaces to define contracts that classes must implement.
မြန်မာလို: class (object တွေ ဖန်တီးဖို့ ပုံစံခွက်) တွေ implement (တကယ် အလုပ်လုပ်အောင် ရေး) လုပ်ရမယ့် contract (လိုက်နာရမယ့် သဘောတူချက်) တွေကို သတ်မှတ်ဖို့ interface (class တစ်ခု implement လုပ်ရမယ့် method စာရင်း) တွေကို သုံးနိုင်ရပါမယ်။
ဒီစာမျက်နှာက HL အဆင့်မှာပဲ စစ်ဆေးတဲ့ အကြောင်းအရာ ဖြစ်ပါတယ်။ SL (Standard Level) နဲ့ HL (Higher Level) ဆိုတာ IB Computer Science (နိုင်ငံတကာ ကျောင်းတွေမှာ သင်တဲ့ ကွန်ပျူတာသိပ္ပံ သင်ရိုး) သင်တန်းရဲ့ အဆင့်နှစ်ဆင့် ဖြစ်ပြီး HL အပိုင်းတွေက ပိုနက်နက်ရှိုင်းရှိုင်း လေ့လာရတဲ့ အပိုင်းတွေပါ။
အဓိက အယူအဆများ
Interface ဆိုတာ ဘာလဲ
Interface က contract တစ်ခုကို သတ်မှတ်ပါတယ်: အဲဒါကို implement လုပ်တဲ့ class တိုင်း ရေးပေးရမယ့် method (သီးခြား အလုပ်တစ်ခု လုပ်ပေးတဲ့ code အပိုင်း) signature (method ရဲ့ နာမည်နဲ့ parameter type တွေ) အစုပါ။ Class တစ်ခုက ဘာ လုပ်နိုင်လဲ ဆိုတာကို သတ်မှတ်ပေးပြီး ဘယ်လို လုပ်လဲ ဆိုတာကိုတော့ မသတ်မှတ်ပါဘူး။
public interface Drawable {
void draw();
String getDescription();
}
# Python has no interface keyword. The closest simple equivalent is a plain class
# of method stubs: Python relies on convention (duck typing) where Java enforces a contract.
class Drawable():
def draw(self):
raise NotImplementedError
def get_description(self):
raise NotImplementedError
Interface ထဲမှာ ဒါတွေပဲ ပါပါတယ်:
- Abstract method (body မပါဘဲ ကြေညာချက်ပဲ ပါတဲ့ method) signature တွေ (method body (method ထဲမှာ ရေးထားတဲ့ code) တွေ မပါပါ)
- Constant (ပြောင်းလို့ မရတဲ့ တန်ဖိုး) တွေ (default (သတ်မှတ်မထားရင် သုံးတဲ့) အနေနဲ့
public static finalဖြစ်ပါတယ်)
Constructor (object ဖန်တီးချိန် attribute တွေကို စတင် သတ်မှတ်ပေးတဲ့ method)၊ instance variable (object တစ်ခုချင်းရဲ့ ကိုယ်ပိုင် variable) နဲ့ method implementation (တကယ် အလုပ်လုပ်အောင် ရေးထားတဲ့ code) တွေ လုံးဝ မပါပါဘူး။
ဒီစာမျက်နှာနဲ့ လက်ရှိ IB Computer Science သင်ရိုးက interface ကို ဒီလို သတ်မှတ်ပါတယ်၊ စာမေးပွဲ အဖြေတွေမှာ သုံးရမယ့် အဓိပ္ပာယ်လည်း ဒါပါပဲ။ Java version အသစ်တွေမှာတော့ interface ထဲမှာ default method body တစ်ခု ထည့်ထားခွင့် ရှိပြီး implement လုပ်တဲ့ class တွေက အဲဒါကို အမွေရပါတယ်။ ဒါကို library (အသင့်ရေးထားပြီး ယူသုံးလို့ရတဲ့ code အစု) code တွေမှာ တွေ့ရပါလိမ့်မယ်၊ အောက်က နှိုင်းယှဉ်ဇယားမှာ ဒါက ဘယ်နေရာမှာ ကွာခြားမှုကို ပြောင်းစေလဲ ဆိုတာ မှတ်ထားပါတယ်။
Interface ကို Implement လုပ်ခြင်း
Class တစ်ခုက interface တစ်ခုကို လက်ခံ လိုက်နာဖို့ implements keyword (programming language မှာ အထူး အဓိပ္ပာယ်ရှိတဲ့ စကားလုံး) ကို သုံးပါတယ်။ ပြီးရင် interface ထဲမှာ ကြေညာထားတဲ့ method တိုင်းအတွက် body ကို ရေးပေးရပါမယ်:
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
@Override
public String getDescription() {
return "Circle (r=" + radius + ")";
}
}
public class TextBox implements Drawable {
private String text;
public TextBox(String text) {
this.text = text;
}
@Override
public void draw() {
System.out.println("Rendering text: " + text);
}
@Override
public String getDescription() {
return "TextBox: " + text;
}
}
class Circle(Drawable): # "implements" = inherit from the stub class
def __init__(self, radius):
self._radius = radius
def draw(self):
print("Drawing a circle with radius", self._radius)
def get_description(self):
return "Circle (r=" + str(self._radius) + ")"
class TextBox(Drawable):
def __init__(self, text):
self._text = text
def draw(self):
print("Rendering text:", self._text)
def get_description(self):
return "TextBox: " + self._text
Class တစ်ခုက implements Drawable လို့ ရေးထားပေမယ့် draw() နဲ့ getDescription() ကို ရေးမထားရင် compiler (code တစ်ခုလုံးကို ကြိုတင် ဘာသာပြန်တဲ့ program) က compile error (compile လုပ်ချိန်မှာ ဖြစ်တဲ့ error) ပြပါတယ်။ (Python မှာ ဒီလို စစ်ဆေးမှု မရှိပါဘူး: ရေးဖို့ မေ့ခဲ့တဲ့ method က runtime (program run နေစဉ်) မှာ ပထမဆုံး ခေါ်တဲ့အခါမှပဲ error ဖြစ်ပါတယ်။)
Interface ဆိုတာ ကတိ တစ်ခုပါ။ Class တစ်ခုက interface ကို implement လုပ်ရင် interface ကြေညာထားတဲ့ method အားလုံးကို ရေးပေးမယ်လို့ အာမခံပါတယ်။ တခြား code တွေက အဲဒီ class အတိအကျကို မသိဘဲနဲ့ ဒီ အာမခံချက်ကို အားကိုးလို့ ရပါတယ်။
Interface ကို Type အဖြစ် သုံးခြင်း
Abstract class (object တိုက်ရိုက် မဖန်တီးနိုင်တဲ့ class) တွေလိုပဲ interface တွေကိုလည်း variable (တန်ဖိုး သိမ်းထားတဲ့ နာမည်ပေးထားတဲ့ နေရာ)၊ parameter (method ကို ပေးလိုက်တဲ့ တန်ဖိုးကို လက်ခံတဲ့ variable) နဲ့ array (အရွယ်အစား ပုံသေ၊ အမျိုးအစားတူ ဒေတာစု) တွေရဲ့ type (အမျိုးအစား) အဖြစ် သုံးလို့ ရပါတယ်:
Drawable[] canvas = new Drawable[3];
canvas[0] = new Circle(5);
canvas[1] = new TextBox("Hello");
canvas[2] = new Circle(3);
for (int i = 0; i < canvas.length; i++) {
System.out.println(canvas[i].getDescription());
canvas[i].draw();
}
canvas = []
canvas.append(Circle(5.0)) # .0 mirrors Java's double, so "r=5.0" prints
canvas.append(TextBox("Hello"))
canvas.append(Circle(3.0))
for i in range(len(canvas)):
print(canvas[i].get_description())
canvas[i].draw()
Output (program က ထုတ်ပြတဲ့ ရလဒ်):
Circle (r=5.0)
Drawing a circle with radius 5.0
TextBox: Hello
Rendering text: Hello
Circle (r=3.0)
Drawing a circle with radius 3.0
Loop (ထပ်ခါထပ်ခါ run တဲ့ code အပိုင်း) က element (အစုထဲက အချက်) တစ်ခုစီဟာ Circle လား TextBox လား ဆိုတာကို မသိသလို ဂရုလည်း မစိုက်ပါဘူး။ Element တစ်ခုစီက Drawable ဖြစ်တယ်၊ ဒါကြောင့် draw() နဲ့ getDescription() ပါတယ် ဆိုတာကိုပဲ သိပါတယ်။
Interface အများ
Class တစ်ခုက interface အများ ကို implement လုပ်နိုင်ပါတယ်။ ဒါက inheritance (parent class ကနေ အမွေဆက်ခံခြင်း) ထက် အဓိက သာတဲ့ အချက်ပါ၊ inheritance မှာတော့ class တစ်ခုက parent တစ်ခုကိုပဲ extend (အမွေဆက်ခံ) လုပ်နိုင်ပါတယ်:
public interface Printable {
void print();
}
public interface Saveable {
void save(String filename);
}
public class Document implements Printable, Saveable {
private String content;
public Document(String content) {
this.content = content;
}
@Override
public void print() {
System.out.println("Printing: " + content);
}
@Override
public void save(String filename) {
System.out.println("Saving to " + filename);
}
}
# Python has no implements keyword - a class can simply inherit from BOTH stub
# classes (Python allows multiple inheritance; a Java class cannot extend two classes)
class Printable():
def print(self):
raise NotImplementedError
class Saveable():
def save(self, filename):
raise NotImplementedError
class Document(Printable, Saveable):
def __init__(self, content):
self._content = content
def print(self):
print("Printing:", self._content)
def save(self, filename):
print("Saving to", filename)
Document က Printable ရော Saveable ပါ implement လုပ်ပါတယ်။ အခြေအနေပေါ် မူတည်ပြီး Printable[] array ထဲမှာ ဒါမှမဟုတ် Saveable[] array ထဲမှာ သိမ်းလို့ ရပါတယ်။ Single inheritance (parent class တစ်ခုတည်းကနေပဲ အမွေဆက်ခံခြင်း) တစ်ခုတည်းနဲ့ဆိုရင် ဒီလို ပြောင်းလွယ်ပြင်လွယ် ရှိဖို့ မဖြစ်နိုင်ပါဘူး။
Java က single inheritance (
extendsတစ်ခုတည်း) ကိုပဲ ခွင့်ပြုပေမယ့် interface အများကို implement လုပ်တာ (implementsအများ) ကိုတော့ ခွင့်ပြုပါတယ်။ Java က multiple inheritance (parent class အများကနေ အမွေဆက်ခံခြင်း) ရဲ့ အကျိုးကျေးဇူးတွေကို ရှုပ်ထွေးမှု မပါဘဲ ဒီနည်းနဲ့ ပေးပါတယ်။
Interface နဲ့ Inheritance ကို ပေါင်းသုံးခြင်း
Class တစ်ခုက parent class (အမွေပေးတဲ့ class) တစ်ခုကို extend လုပ်တာ ရော interface တစ်ခု ဒါမှမဟုတ် တစ်ခုထက်ပိုပြီး implement လုပ်တာ ပါ တစ်ပြိုင်နက် လုပ်နိုင်ပါတယ်:
public abstract class Shape {
private String colour;
public Shape(String colour) {
this.colour = colour;
}
public String getColour() { return colour; }
public abstract double getArea();
}
public class Circle extends Shape implements Drawable {
private double radius;
public Circle(String colour, double radius) {
super(colour);
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public void draw() {
System.out.println("Drawing " + getColour() + " circle");
}
@Override
public String getDescription() {
return getColour() + " circle (r=" + radius + ")";
}
}
import math
class Shape():
def __init__(self, colour):
self._colour = colour
def get_colour(self):
return self._colour
def get_area(self):
raise NotImplementedError # "abstract" - Python has no abstract keyword
class Circle(Shape, Drawable): # inherit the parent class AND the contract class
def __init__(self, colour, radius):
super().__init__(colour) # call the parent (Shape) constructor
self._radius = radius
def get_area(self):
return math.pi * self._radius * self._radius
def draw(self):
print("Drawing", self.get_colour(), "circle")
def get_description(self):
return self.get_colour() + " circle (r=" + str(self._radius) + ")"
Circle က Shape ကနေ အမွေဆက်ခံပါတယ် (colour ကို ရပြီး getArea() ကို ရေးဖို့ လိုပါတယ်)၊ ပြီးတော့ Drawable ကို implement လုပ်ပါတယ် (draw() နဲ့ getDescription() ကို ရေးဖို့ လိုပါတယ်)။ extends အပိုင်းက implements ရဲ့ ရှေ့မှာ လာပါတယ်။ (Python မှာတော့ အလုပ် နှစ်ခုလုံးအတွက် syntax (code ရေးထုံး) တူတူပဲ သုံးပါတယ်: class header ရဲ့ ကွင်းထဲမှာ parent class နဲ့ contract class ကို တွဲရေးပါတယ်။)
Interface နဲ့ Abstract Class နှိုင်းယှဉ်ချက်
| အချက် | Abstract Class | Interface |
|---|---|---|
| Keyword | abstract class | interface |
| ယူသုံးပုံ | extends (တစ်ခုတည်းပဲ) | implements (အများ ရပါတယ်) |
| Constructor | ရှိပါတယ် | မရှိပါ |
| Instance variable | ရှိပါတယ် | မရှိပါ (constant တွေပဲ) |
| Concrete (abstract မဟုတ်တဲ့ ပုံမှန်) method | ရှိပါတယ် (မျှသုံးတဲ့ လုပ်ဆောင်ပုံ) | မရှိပါ (signature တွေပဲ၊ Java အသစ်တွေမှာ default method body တွေ ထားခွင့် ရှိပေမယ့် syllabus မှာ မပါပါဘူး) |
| Abstract method | ရှိပါတယ် (တချို့ ဒါမှမဟုတ် အားလုံး) | Method အားလုံး abstract ပါ |
| ဘယ်အချိန် သုံးမလဲ | Class တွေမှာ တူညီတဲ့ state (attribute တွေမှာ လက်ရှိ ရှိနေတဲ့ တန်ဖိုးများ) နဲ့ behaviour (object က လုပ်နိုင်တာတွေ) ရှိတဲ့အခါ | ဆက်စပ်မှု မရှိတဲ့ class တွေမှာ စွမ်းရည် တူတူ ရှိတဲ့အခါ |
Abstract class ကို ဘယ်အချိန် သုံးမလဲ:
- Subclass (အမွေဆက်ခံတဲ့ child class) တွေက attribute (object ရဲ့ ဒေတာကို သိမ်းတဲ့ variable) တွေနဲ့ concrete method တွေကို မျှသုံးတဲ့အခါ (ဥပမာ
name,age,getName()ပါတဲ့Animal) - ရှင်းလင်းတဲ့ is-a (X က Y တစ်မျိုး ဖြစ်တယ် ဆိုတဲ့ ဆက်နွယ်မှု) hierarchy (parent နဲ့ child class တွေကို အဆင့်ဆင့် ဖွဲ့ထားတဲ့ ပုံစံ) ရှိတဲ့အခါ
Interface ကို ဘယ်အချိန် သုံးမလဲ:
- ဆက်စပ်မှု မရှိတဲ့ class အများမှာ တူညီတဲ့ စွမ်းရည် လိုတဲ့အခါ (ဥပမာ
Drawable,Comparable,Serializable) - Class တစ်ခုက contract အများ နဲ့ ကိုက်ညီဖို့ လိုတဲ့အခါ
Abstract class ကို “တစ်ခုခုက ဘာ ဖြစ် လဲ” လို့၊ interface ကို “တစ်ခုခုက ဘာ လုပ်နိုင် လဲ” လို့ မှတ်ထားပါ။
DogကAnimalဖြစ် ပါတယ် (abstract class)၊ ဒါပေမယ့်DogကTrainableဖြစ်နိုင် ပါတယ်၊ ဆိုလိုတာက လေ့ကျင့်ပေးလို့ ရပါတယ် (interface)။
အဆင့်ဆင့် ရှင်းပြထားတဲ့ ဥပမာများ
ဥပမာ 1: နှိုင်းယှဉ်လို့ရတဲ့ Item များ
ကျောင်းသုံး app တစ်ခုက ကျောင်းဆိုင်ထဲက ကုန်ပစ္စည်း (product) တွေနဲ့ ကျောင်းသားတွေကို တစ်မျိုးချင်း မတူတဲ့ စံနှုန်းတွေနဲ့ စီဖို့ လိုပါတယ်။ နှစ်မျိုးလုံးကို နှိုင်းယှဉ်လို့ ရပေမယ့် လုံးဝ မဆိုင်တဲ့ class တွေပါ။
public interface Sortable {
int getSortKey();
}
public class Product implements Sortable {
private String name;
private double price;
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() { return name; }
public double getPrice() { return price; }
@Override
public int getSortKey() {
return (int) (price * 100); // sort by price in cents
}
}
public class Student implements Sortable {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() { return name; }
public int getScore() { return score; }
@Override
public int getSortKey() {
return score; // sort by score
}
}
# The "interface" is a stub class - the real contract is the shared method name
class Sortable():
def get_sort_key(self):
raise NotImplementedError
class Product(Sortable):
def __init__(self, name, price):
self._name = name
self._price = price
def get_name(self):
return self._name
def get_price(self):
return self._price
def get_sort_key(self):
return int(self._price * 100) # sort by price in cents
class Student(Sortable):
def __init__(self, name, score):
self._name = name
self._score = score
def get_name(self):
return self._name
def get_score(self):
return self._score
def get_sort_key(self):
return self._score # sort by score
Sort method တစ်ခုတည်းက ဘယ် Sortable array မှာမဆို အလုပ်လုပ်ပါတယ်:
// Selection sort that works on ANY Sortable objects
public static void sort(Sortable[] items) {
for (int i = 0; i < items.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < items.length; j++) {
if (items[j].getSortKey() < items[minIndex].getSortKey()) {
minIndex = j;
}
}
Sortable temp = items[minIndex];
items[minIndex] = items[i];
items[i] = temp;
}
}
# Selection sort that works on ANY objects with get_sort_key() -
# duck typing: Python never checks the type, only that the method exists
def sort(items):
for i in range(len(items) - 1):
min_index = i
for j in range(i + 1, len(items)):
if items[j].get_sort_key() < items[min_index].get_sort_key():
min_index = j
temp = items[min_index]
items[min_index] = items[i]
items[i] = temp
Product[] products = {
new Product("Laptop", 999.99),
new Product("Mouse", 29.99),
new Product("Keyboard", 79.99)
};
sort(products);
for (int i = 0; i < products.length; i++) {
System.out.println(products[i].getName() + ": $" + products[i].getPrice());
}
products = [
Product("Laptop", 999.99),
Product("Mouse", 29.99),
Product("Keyboard", 79.99)
]
sort(products)
for i in range(len(products)):
print(products[i].get_name() + ": $" + str(products[i].get_price()))
Output:
Mouse: $29.99
Keyboard: $79.99
Laptop: $999.99
sort() method က Product ကိုလည်း Student ကိုလည်း မသိပါဘူး။ Sortable interface ရဲ့ contract ကိုပဲ အားကိုးပါတယ်။
ဥပမာ 2: Interface အများ
စက်ပစ္စည်းတွေကို ထိန်းချုပ်လို့လည်း ရ၊ စောင့်ကြည့်လို့လည်း ရတဲ့ smart home စနစ် တစ်ခုပါ။
public interface Controllable {
void turnOn();
void turnOff();
boolean isOn();
}
public interface Monitorable {
String getStatus();
}
public class SmartLight implements Controllable, Monitorable {
private String room;
private boolean on;
public SmartLight(String room) {
this.room = room;
this.on = false;
}
@Override
public void turnOn() { on = true; }
@Override
public void turnOff() { on = false; }
@Override
public boolean isOn() { return on; }
@Override
public String getStatus() {
return room + " light: " + (on ? "ON" : "OFF");
}
}
public class Thermostat implements Controllable, Monitorable {
private double temperature;
private boolean on;
public Thermostat(double temperature) {
this.temperature = temperature;
this.on = false;
}
@Override
public void turnOn() { on = true; }
@Override
public void turnOff() { on = false; }
@Override
public boolean isOn() { return on; }
@Override
public String getStatus() {
String state = on ? "heating to " + temperature + "C" : "OFF";
return "Thermostat: " + state;
}
}
# Two "interfaces" as stub classes - the contract is enforced by convention only
class Controllable():
def turn_on(self):
raise NotImplementedError
def turn_off(self):
raise NotImplementedError
def is_on(self):
raise NotImplementedError
class Monitorable():
def get_status(self):
raise NotImplementedError
class SmartLight(Controllable, Monitorable):
def __init__(self, room):
self._room = room
self._on = False
def turn_on(self):
self._on = True
def turn_off(self):
self._on = False
def is_on(self):
return self._on
def get_status(self):
if self._on == True: # Java's on ? "ON" : "OFF" becomes a plain if/else
return self._room + " light: ON"
else:
return self._room + " light: OFF"
class Thermostat(Controllable, Monitorable):
def __init__(self, temperature):
self._temperature = temperature
self._on = False
def turn_on(self):
self._on = True
def turn_off(self):
self._on = False
def is_on(self):
return self._on
def get_status(self):
if self._on == True:
state = "heating to " + str(self._temperature) + "C"
else:
state = "OFF"
return "Thermostat: " + state
Controllable[] devices = {
new SmartLight("Kitchen"),
new Thermostat(22.0)
};
// Turn everything on
for (int i = 0; i < devices.length; i++) {
devices[i].turnOn();
}
// Check status (need to cast to Monitorable)
for (int i = 0; i < devices.length; i++) {
Monitorable m = (Monitorable) devices[i];
System.out.println(m.getStatus());
}
devices = [
SmartLight("Kitchen"),
Thermostat(22.0)
]
# Turn everything on
for i in range(len(devices)):
devices[i].turn_on()
# Check status - Python needs NO cast: if the object has get_status(), the call works
for i in range(len(devices)):
print(devices[i].get_status())
Output:
Kitchen light: ON
Thermostat: heating to 22.0C
SmartLight ရော Thermostat ပါ interface နှစ်ခုကို implement လုပ်ပါတယ်။ Code က ဘာလိုလဲ ဆိုတာပေါ် မူတည်ပြီး သူတို့ကို Controllable (ဖွင့်ဖို့၊ ပိတ်ဖို့) အဖြစ် ဒါမှမဟုတ် Monitorable (status စစ်ဖို့) အဖြစ် ဆက်ဆံလို့ ရပါတယ်။
Quick Check (အမြန် စစ်ဆေးမေးခွန်း)
Q1. Interface ထဲမှာ ဘာတွေ ပါသလဲ။
Q2. Class တစ်ခုက interface ဘယ်နှစ်ခုကို implement လုပ်နိုင်သလဲ။
Q3. Class တစ်ခုက Drawable ကို implement လုပ်ပေမယ့် draw() method ကို ရေးမထားပါဘူး။ ဘာဖြစ်မလဲ။
Q4. Abstract class အစား interface ကို ဘယ်အချိန်မှာ သုံးသင့်သလဲ။
Q5. Class တစ်ခုကို extend လုပ်တာ ရော interface တစ်ခုကို implement လုပ်တာ ပါ တစ်ပြိုင်နက် ရေးတဲ့ မှန်ကန်တဲ့ syntax က ဘာလဲ။
Trace Exercise (code ကို တစ်ဆင့်ချင်း လိုက်ကြည့်ခြင်း)
Interface method call (method ကို ခေါ်သုံးခြင်း) တွေကို trace (တစ်ဆင့်ချင်း လိုက်ပြီး မှတ်) လုပ်ပါ။ SmartLight နဲ့ Thermostat နှစ်ခုလုံးက Controllable နဲ့ Monitorable ကို implement လုပ်ပါတယ်။ အဖြေတွေကို code ရဲ့ တန်ဖိုးနဲ့ output အတိုင်း English လို ရိုက်ထည့်ပါ (ဥပမာ true, false)။
Trace: Interface ကနေ method ခေါ်ပုံ
SmartLight light = new SmartLight("Living Room");
Thermostat thermo = new Thermostat(21.5);
light.turnOn();
thermo.turnOn();
thermo.turnOff();| စက်ပစ္စည်း | isOn() | getStatus() |
|---|---|---|
| light | ||
| thermo |
Thermostat ကို on လုပ်ပြီးနောက် ပြန် off လုပ်ထားပါတယ်။ နောက်ဆုံး state က off ပါ။
Spot the Error (အမှား ရှာခြင်း)
ဒီ code က interface တစ်ခုနဲ့ အဲဒါကို implement လုပ်ရမယ့် class တစ်ခုကို သတ်မှတ်ထားပါတယ်။ အမှားကို ရှာပါ။
အမှား ရှာပါ: Media player interface တစ်ခုပါ။ AudioPlayer class က play(), stop() နဲ့ pause() ကို ကြေညာထားတဲ့ Playable ထဲက method အားလုံးကို implement လုပ်ရပါမယ်။
Line 8 အတွက် မှန်ကန်တဲ့ ပြင်နည်းကို ရွေးပါ:
Predict the Output (output ကို ကြိုခန့်မှန်းခြင်း)
အဓိက အယူအဆများ အပိုင်းက Drawable interface ကို သုံးပါ။ အဲဒီမှာ Circle.getDescription() က "Circle (r=" + radius + ")" ကို၊ TextBox.getDescription() က "TextBox: " + text ကို return ပြန်ပေးပါတယ်။ ဒီ code က ဘာကို print ထုတ်မလဲ။
Drawable[] canvas = new Drawable[2];
canvas[0] = new Circle(5);
canvas[1] = new TextBox("Hello");
System.out.println(canvas[0].getDescription());
System.out.println(canvas[1].getDescription());Line နှစ်ကြောင်းလုံးကို \n နဲ့ ခြားပြီး ရိုက်ထည့်ပါ:
Practice Exercises (လေ့ကျင့်ခန်းများ)
Core (အခြေခံ အဆင့်)
-
Measurable interface:
double getMeasurement()method ပါတဲ့Measurableinterface တစ်ခု ဖန်တီးပါ။ Class နှစ်ခု ဖန်တီးပါ:Ruler(သူ့ အရှည်ကို cm နဲ့ return ပြန်ပေးတယ်) နဲ့Thermometer(လက်ရှိ အပူချိန်ကို return ပြန်ပေးတယ်)။ နှစ်ခုလုံးကိုMeasurable[]array ထဲမှာ သိမ်းပြီး တိုင်းတာချက် တစ်ခုစီကို print ထုတ်ပါ။ -
Interface type:
Drawable[] items = new Drawable[3];ကို ပေးထားပါတယ်။items[0] = new Drawable();က ဘာကြောင့် compile error ဖြစ်စေပြီးitems[0] = new Circle(5);ကတော့ ဘာကြောင့် အလုပ်လုပ်လဲဆိုတာ explain (ရှင်းပြပါ) လုပ်ပါ (Circle က Drawable ကို implement လုပ်တယ်လို့ ယူဆပါ)။
Extension (တိုးချဲ့ အဆင့်)
-
Interface နှစ်ခု:
Readable(String read()ပါတယ်) နဲ့Writable(void write(String data)ပါတယ်) interface တွေကို ဖန်တီးပါ။ နှစ်ခုလုံးကို implement လုပ်တဲ့Fileclass တစ်ခု ဖန်တီးပါ။Readableကိုပဲ implement လုပ်တဲ့Keyboardclass တစ်ခု ဖန်တီးပါ။ Interface type တွေကို polymorphic array (မတူတဲ့ class တွေရဲ့ object တွေကို type တစ်ခုတည်းနဲ့ အတူ သိမ်းထားတဲ့ array) တွေအတွက် သုံးပုံကို ပြပါ။ -
Compare and contrast (တူတာနဲ့ ကွာတာကို နှိုင်းယှဉ်ပါ): Abstract Classes စာမျက်နှာက abstract
Shapeclass ကိုShapeSpecလို့ ခေါ်တဲ့ interface အဖြစ် ပြန်ရေးပါ။ ဘာတွေ ဆုံးရှုံးသွားလဲ။ ဘာတွေ ရလာလဲ။ Shape တွေအတွက် ဘယ်နည်းက ပိုကောင်းလဲ၊ ဘာကြောင့်လဲ။
Challenge (စိန်ခေါ်မှု အဆင့်)
- Plugin စနစ်:
String getName(),void execute()နဲ့int getPriority()method တွေ ပါတဲ့Plugininterface တစ်ခုကို Design (အစီအစဉ် ဒါမှမဟုတ် model တစ်ခု ရေးဆွဲပါ) လုပ်ပါ။SpellChecker,WordCounterနဲ့AutoSaverဆိုတဲ့ concrete plugin (program ထဲ ထပ်ထည့်လို့ရတဲ့ သီးခြား အစိတ်အပိုင်း) သုံးခု ဖန်တီးပါ။ Plugin တွေကို array ထဲမှာ သိမ်းပြီး priority (ဦးစားပေး အဆင့်) အလိုက် စီကာ (အနိမ့်ဆုံး အရင်) အစဉ်အတိုင်း execute လုပ်ပေးတဲ့PluginManagerclass ကို ရေးပါ။
ဆက်စပ် ခေါင်းစဉ်များ
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Abstract Classes: interface တွေက abstraction (မလိုတဲ့ အသေးစိတ်ကို ဖယ်ပြီး အဓိကကိုပဲ ကြည့်ခြင်း) ကို ပိုပြီး ရှေ့ဆက်ပါတယ်
- အရင် လေ့လာထားရမယ့် ခေါင်းစဉ်: Polymorphism (ပုံစံ အမျိုးမျိုး ယူနိုင်ခြင်း): interface တွေက ဆက်စပ်မှု မရှိတဲ့ class တွေကြားမှာ polymorphism ကို ဖြစ်နိုင်စေပါတယ်
- နောက်ထပ် လေ့လာမယ့် ခေါင်းစဉ်: Composition vs Inheritance: has-a (X ထဲမှာ Y ပါတယ် ဆိုတဲ့ ဆက်နွယ်မှု) နဲ့ is-a၊ tight coupling (class တွေ အချင်းချင်း အလွန် မှီခိုနေခြင်း)၊ composition (ပိုခိုင်မာတဲ့ has-a ဆက်နွယ်မှု) ကို ဦးစားပေးခြင်း
- ဆက်စပ် ခေါင်းစဉ်: Encapsulation (ဒေတာနဲ့ method ကို တစ်စုတည်း ထုပ်ပိုးခြင်း): interface တွေက implementation ကို ဖုံးထားပေးလို့ encapsulation ကို လိုက်နာစေပါတယ်
- ဆက်စပ် ခေါင်းစဉ်: UML Class Diagrams (class တစ်ခုကို အကွက် သုံးကွက်နဲ့ ပြတဲ့ ပုံများ): UML (class တွေကို ပုံနဲ့ ပြတဲ့ စံ ရေးဆွဲနည်း) မှာ interface တွေကို အစက်ချ မြှား (dashed arrow) တွေနဲ့ ပြပါတယ်