Hi! Ngayon ay pag-uusapan natin ang tungkol sa isa sa mga espesyal na uri ng data ng Java:
Parang hindi naman problematic diba? Kailangan lang nating matukoy kung anong mga katangian ang mayroon ang anumang buwan. Marahil kailangan muna natin ang pangalan ng buwan at ang bilang ng mga araw dito. Ang solusyon ay mukhang medyo simple:
Ang may-akda ay isa sa mga tagalikha ng Java, kaya siguradong mapagkakatiwalaan mo ang kanyang payo kung paano gamitin nang tama at mahusay ang mga tool ng wika :) Tungkol sa aming aralin, inirerekomenda kong bigyan mo ng espesyal na pansin ang kabanata ng aklat sa
Enum
(maikli para sa "enumeration"). Ano ang ginagawa nitong espesyal? Isipin natin kung ano ang kailangan nating ipatupad ang "mga buwan" sa isang programa. 
public class Month {
private String name;
private int daysCount;
public Month(String name, int daysCount) {
this.name = name;
this.daysCount = daysCount;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDaysCount() {
return daysCount;
}
public void setDaysCount(int daysCount) {
this.daysCount = daysCount;
}
@Override
public String toString() {
return "Month{" +
"name='" + name + '\'' +
", daysCount=" + daysCount +
'}';
}
}
Ang buong shabang! Mayroon kaming Month
klase, ang mga kinakailangang field, getter/setter, at toString()
. Maliban kung, siyempre, kailangan nating magdagdag equals()
athashCode()
upang makamit ang ganap na kaligayahan :) Ngunit dito mayroon kaming isang konseptong problema. Tulad ng malamang na natatandaan mo, ang isa sa mga pangunahing bentahe ng OOP ay ginagawa nitong madali ang pagmodelo ng mga entity mula sa totoong mundo. Isang upuan, isang kotse, isang planeta — lahat ng mga konseptong ito mula sa ordinaryong buhay ay madaling kinakatawan sa isang programa sa tulong ng abstraction. Ang problema ay ang ilang real-world na entity ay may mahigpit na limitadong hanay ng mga halaga. May 4 na season lang sa isang taon. May 8 notes lang sa isang octave. Ang kalendaryo ay may 12 buwan lamang. At ang Danny Ocean ng Ocean's 11 ay may 11 kaibigan lamang (bagaman hindi ito mahalaga :)) Ang mahalaga ay ang isang ordinaryong Java class ay hindi nagagawang imodelo ang mga entity na ito at ipatupad ang kanilang mga natural na limitasyon. Ang amingMonth
nasa klase ang lahat ng kinakailangang field. Ngunit kung gagamitin ito ng ibang programmer, walang makakapigil sa kanya sa paglikha ng ganap na nakakabaliw na mga bagay:
public class Main {
Month month1 = new Month("lolkek", 322);
Month month2 = new Month("yahoooooooooooo", 12345);
}
Kung ito ay lilitaw sa aming code, hindi magiging madali upang mahanap ang salarin! Sa isang banda, ang programmer na lumilikha ng mga bagay ay maaaring mapagtanto na ang Month
klase ay nangangahulugang "buwan sa isang taon" at hindi sumulat ng gayong katarantaduhan. Sa kabilang banda, sinasamantala lamang ng programmer ang mga kakayahan na ibinigay ng taga-disenyo ng klase. Posible bang magtalaga ng mga arbitrary na pangalan at bilang ng mga araw? Iyon mismo ang nakuha namin. Ano ang dapat nating gawin sa sitwasyong ito? Sa totoo lang, bago ilabas ang Java 1.5, kailangang maging malikhain ang mga programmer :) Noong mga panahong iyon, gumawa sila ng mga istrukturang tulad nito:
public class Month {
private String name;
private int daysCount;
private Month(String name, int daysCount) {
this.name = name;
this.daysCount = daysCount;
}
public static Month JANUARY = new Month("January", 31);
public static Month FEBRUARY = new Month("February", 28);
public static Month MARCH = new Month("March", 31);
@Override
public String toString() {
return "Month{" +
"name='" + name + '\'' +
", daysCount=" + daysCount +
'}';
}
}
Dito ay pinutol namin ang bilang ng mga buwan mula labindalawa hanggang tatlo upang gawing mas maikli ang halimbawa. Ang ganitong mga disenyo ay naging posible upang malutas ang problema. Ang kakayahang lumikha ng mga bagay ay limitado sa isang pribadong tagabuo:
private Month(String name, int daysCount) {
this.name = name;
this.daysCount = daysCount;
}
Ang mga programmer na gumagamit ng klase ay hindi maaaring gumawa Month
ng mga bagay. Kinailangan nilang gamitin ang huling mga static na bagay na ibinigay ng developer ng klase. Halimbawa, tulad nito:
public class Main {
public static void main(String[] args) {
Month january = Month.JANUARY;
System.out.println(january);
}
}
Ngunit, binigyang pansin ng mga developer ng Java ang umiiral na problema. Siyempre, napakaganda na ang mga programmer ay nakagawa ng solusyon gamit ang mga tool na magagamit sa wika, ngunit mukhang hindi ito napakadali! Ang isang malinaw na solusyon ay kailangan, kahit na para sa mga baguhan. At kaya Enum
lumitaw sa Java. Karaniwan, Enum
ay isang klase ng Java na nagbibigay ng limitadong hanay ng mga halaga ng bagay. Narito ang hitsura nito:
public enum Month {
JANUARY,
FEBRUARY,
MARCH
}
Sa kahulugan, ipinahiwatig namin na iyon Enum
ay isang klase ng Java, ngunit totoo ba iyon? Oo, at maaari pa naming i-verify ito. Halimbawa, subukang gawing Month
magmana ang aming enum ng ibang klase:
public abstract class AbstractMonth {
}
// Error! The extends clause cannot be used with an enum
public enum Month extends AbstractMonth {
JANUARY,
FEBRUARY,
MARCH
}
Bakit nangyayari iyon? Kapag sumulat tayo:
public enum Month
kino-convert ng compiler ang pahayag na ito sa sumusunod na code:
public Class Month extends Enum
Tulad ng alam mo na, hindi sinusuportahan ng Java ang maramihang pamana. Samakatuwid, hindi tayo maaaring magmana AbstractMonth
. Paano Enum
magagamit ang bagong construct na ito, ,? At paano ito naiiba sa lumang konstruksyon na may static final
mga patlang? Well, bilang isang halimbawa, ang lumang konstruksyon ay hindi nagpapahintulot sa amin na gamitin ang aming sariling hanay ng mga halaga sa switch
mga pahayag. Isipin na gusto naming lumikha ng isang programa na magpapaalala sa amin ng mga pista opisyal na ipinagdiriwang bawat buwan:
public class HolidayReminder {
public void printHolidays(Month month) {
switch (month) {
// Error!
case JANUARY:
}
}
}
Tulad ng nakikita mo, ang tagatala ay nagtatapon ng isang error dito. Ngunit sa sandaling enum
lumitaw sa Java 1.5, ang lahat ay naging mas simple:
public enum Month {
JANUARY,
FEBRUARY,
MARCH
}
public class HolidayReminder {
public void printHolidays(Month month) {
switch (month) {
case JANUARY:
System.out.println("New Year's Day is January 1st!");
break;
case FEBRUARY:
System.out.println("Valentine's Day is February 14th!");
break;
case MARCH:
System.out.println("Saint Patrick's Day is March 17th!");
break;
}
}
}
public class Main {
public static void main(String[] args) {
HolidayReminder reminder = new HolidayReminder();
reminder.printHolidays(Month.JANUARY);
}
}
Output ng console:
New Year's Day is January 1st!
Tandaan na ang pag-access sa Enum
mga bagay ay nanatiling static, tulad noong bago ang Java 1.5. Hindi namin kailangang lumikha ng isang Month
bagay upang ma-access ang mga buwan. Kapag nagtatrabaho sa mga enum, napakahalaga na huwag kalimutan na ito Enum
ay isang ganap na klase. Nangangahulugan ito na, kung kinakailangan, maaari mong tukuyin ang mga konstruktor at mga pamamaraan sa loob nito. Halimbawa, sa nakaraang fragment ng code, tinukoy lang namin ang mga halaga: ENERO, FEBRUARY, MARCH. Gayunpaman, maaari naming palawakin ang aming Month
enum tulad nito:
public enum Month {
JANUARY("January", 31),
FEBRUARY("February", 28),
MARCH("March", 31),
APRIL("April", 30),
MAY("May", 31),
JUNE("June", 30),
JULY("July", 31),
AUGUST("August", 31),
SEPTEMBER("September", 30),
OCTOBER("October", 31),
NOVEMBER("November", 30),
DECEMBER("December", 31);
private String name;
private int daysCount;
Month(String name, int daysCount) {
this.name = name;
this.daysCount = daysCount;
}
public static Month[] getWinterMonths() {
return new Month[]{DECEMBER, JANUARY, FEBRUARY};
}
public static Month[] getSummerMonths() {
return new Month[]{JUNE, JULY, AUGUST};
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getDaysCount() {
return daysCount;
}
public void setDaysCount(int daysCount) {
this.daysCount = daysCount;
}
@Override
public String toString() {
return "Month{" +
"name='" + name + '\'' +
", daysCount=" + daysCount +
'}';
}
}
Dito ibinigay namin ang aming enum
2 field (ang pangalan ng buwan at ang bilang ng mga araw), isang constructor na gumagamit ng mga field na ito, getter/setters, method toString()
, at 2 static na pamamaraan. Tulad ng nakikita mo, walang mga problema dito. Muli, Enum
talagang isang ganap na klase:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
System.out.println(Arrays.toString(Month.getSummerMonths()));
}
}
Output ng console:
[Month{name='June', daysCount=30}, Month{name='July', daysCount=31}, Month{name='August', daysCount=31}]
Sa wakas, gusto kong magrekomenda ng lubhang kapaki-pakinabang na Java book, katulad ng "Effective Java" ni Joshua Bloch . 
Enum
. Masayang pagbabasa! :)
GO TO FULL VERSION