CodeGym /Java Blog /Random /Enum. Mga praktikal na halimbawa. Pagdaragdag ng mga kons...
John Squirrels
Antas
San Francisco

Enum. Mga praktikal na halimbawa. Pagdaragdag ng mga konstruktor at pamamaraan

Nai-publish sa grupo
Hi! Ngayon ay pag-uusapan natin ang tungkol sa isa sa mga espesyal na uri ng data ng Java: Enum(maikli para sa "enumeration"). Ano ang ginagawa nitong espesyal? Isipin natin kung ano ang kailangan nating ipatupad ang "mga buwan" sa isang programa. Enum.  Mga praktikal na halimbawa.  Pagdaragdag ng mga konstruktor at pamamaraan - 1 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:

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 Monthklase, 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 amingMonthnasa 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 Monthklase 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 Monthng 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 Enumlumitaw sa Java. Karaniwan, Enumay 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 Enumay isang klase ng Java, ngunit totoo ba iyon? Oo, at maaari pa naming i-verify ito. Halimbawa, subukang gawing Monthmagmana 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 Enummagagamit ang bagong construct na ito, ,? At paano ito naiiba sa lumang konstruksyon na may static finalmga patlang? Well, bilang isang halimbawa, ang lumang konstruksyon ay hindi nagpapahintulot sa amin na gamitin ang aming sariling hanay ng mga halaga sa switchmga 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 enumlumitaw 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 Enummga bagay ay nanatiling static, tulad noong bago ang Java 1.5. Hindi namin kailangang lumikha ng isang Monthbagay upang ma-access ang mga buwan. Kapag nagtatrabaho sa mga enum, napakahalaga na huwag kalimutan na ito Enumay 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 Monthenum 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 enum2 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, Enumtalagang 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.  Mga praktikal na halimbawa.  Pagdaragdag ng mga konstruktor at pamamaraan - 3Ang 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. Masayang pagbabasa! :)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION