JavaRush /Java Blog /Random-TL /Enum sa Java. Mga praktikal na halimbawa. Pagdaragdag ng ...

Enum sa Java. Mga praktikal na halimbawa. Pagdaragdag ng mga Konstruktor at Paraan

Nai-publish sa grupo
Kamusta! Ngayon ay pag-uusapan natin ang tungkol sa isang espesyal na uri ng data sa Java - Enum(maikli para sa enumeration). Ano ang kanilang tampok? Isipin natin na kailangan nating ipatupad ang mga buwan sa programa. Enum.  Mga praktikal na halimbawa.  Pagdaragdag ng mga konstruktor at pamamaraan - 1Mukhang, ano ang problema? Kailangan mo lang matukoy kung anong mga ari-arian mayroon ang anumang buwan. Marahil kailangan natin, una sa lahat, ang pangalan ng buwan at ang bilang ng mga araw dito. Ang solusyon sa problema 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 +
               '}';
   }
}
Full set po! Mayroon kaming klase Month, ang mga kinakailangang field, getters-setters, toString(). Maliban kung kailangan equals()mong hashCode()idagdag ito para sa kumpletong kaligayahan :) Gayunpaman, mayroon kaming isang konseptong problema. Tulad ng natatandaan mo, ang isa sa mga pangunahing bentahe ng OOP ay ginagawa nitong madali ang pag-modelo ng mga real-world na entity. Isang upuan, isang kotse, isang planeta - lahat ng mga konseptong ito mula sa pang-araw-araw na buhay ay madaling katawanin sa isang programa gamit ang abstraction. Ang problema ay ang ilang entity sa totoong mundo ay may mahigpit na limitadong hanay ng mga kahulugan. Mayroon lamang 4 na panahon sa isang taon. Mayroon lamang 7 mga tala sa musika. Mayroon lamang 12 buwan sa kalendaryo. Ang Ocean ay mayroon lamang 11 na kaibigan (bagaman ito ay mapagtatalunan :)) Sa madaling salita, ang isang regular na klase ng Java ay hindi magagawang i-modelo ang mga entity na ito at igalang ang kanilang mga likas na hadlang. Nasa klase namin Monthang lahat ng kinakailangang field. Ngunit kung gagamitin ito ng isa pang programmer, walang makakapigil sa kanya sa paglikha ng mga ganap na nakatutuwang bagay:
public class Main {

   Month month1 = new Month("lolkek", 322);
   Month month2 = new Month("yahoooooooooooo", 12345);

}
Kung ito ay lilitaw sa programa, hindi magiging madali upang mahanap ang salarin! Sa isang banda, ang programmer na lumikha ng mga bagay ay maaaring maunawaan na ang klase Monthay nangangahulugang "buwan ng taon" at hindi sumulat ng gayong katarantaduhan. Sa kabilang banda, sinasamantala lang niya ang mga pagkakataong ibinigay sa kanya ng class designer. Maaari ba akong magtalaga ng anumang mga pangalan at bilang ng mga araw? Siya ang nagtalaga nito. Ano ang gagawin sa ganoong sitwasyon? Bago ang paglabas ng bersyon 1.5 ng wikang Java, ang mga programmer ay kailangang, tapat na nagsasalita, umalis dito :) Noong mga araw na iyon, nilikha nila ang mga sumusunod na konstruksyon:
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("Январь", 31);
   public static Month FEBRUARY = new Month("Февраль", 28);
   public static Month MARCH = new Month("Март", 31);

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
Dito ay pinasimple namin ang bilang ng mga buwan sa tatlo sa halip na labindalawa upang mapanatiling mas maikli ang halimbawa. Ang ganitong mga disenyo ay naging posible upang malutas ang problema. Ang mga opsyon para sa mga nilikhang bagay ay limitado ng isang pribadong tagabuo:
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Ang mga programmer na gumagamit ng klase ay hindi basta makalikha Month. Napilitan silang gamitin ang mga huling static na bagay na ibinigay ng developer ng klase. Ito ay mukhang ganito:
public class Main {

   public static void main(String[] args) {

       Month january = Month.JANUARY;
       System.out.println(january);
   }

}
Gayunpaman, napansin ng mga developer ng Java ang isang umiiral na problema. Siyempre, napakaganda na ang mga programmer ay nakabuo ng solusyon gamit ang mga tool na magagamit sa wika, ngunit hindi ito mukhang napakasimple! Ang isang malinaw na solusyon ay kailangan, naa-access kahit sa mga nagsisimula. Ito ay kung paano lumitaw sa Java Enum. Mahalaga, Enumito ay isang Java class na nagbibigay ng limitadong hanay ng mga value object. Narito ang hitsura nito:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
Sa kahulugan, ipinahiwatig namin na Enumito ay isang klase ng Java, ngunit totoo ba ito? Oo, at maaari pa nating suriin ito. Subukan, halimbawa, ang pagmamana sa atin enum Monthmula sa ibang klase:
public abstract class AbstractMonth {
}

//ошибка! No extends clause allowed to enum
public enum Month extends AbstractMonth {

   JANUARY,
   FEBRUARY,
   MARCH
}
Bakit ito nangyayari? Kapag sumulat kami sa isang programa:
public enum Month
Kino-convert ng compiler ang command na ito sa code na tulad nito:
public Class Month extends Enum
Tulad ng alam mo na, hindi pinapayagan ang maramihang mana sa Java. Samakatuwid, AbstractMonthhindi kami maaaring magmana mula sa. Paano Enummagagamit ang bagong disenyong ito? At paano ito naiiba sa lumang disenyo na may static finalmga patlang? Buweno, halimbawa, ang lumang disenyo ay hindi nagpapahintulot sa amin na gamitin ang aming sariling hanay ng mga halaga sa switch-expression. Isipin na gusto naming lumikha ng isang programa na magpapaalala sa amin kung anong mga pista opisyal ang ipinagdiriwang ngayong buwan:
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
Dito, tulad ng nakikita mo, ang tagatala ay nagtatapon ng isang error. Ngunit pagkatapos lumitaw ang Java 1.5 enum, 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("7 января будет Рождество!");
               break;
           case FEBRUARY:
               System.out.println("В феврале празднуется День Защитника Отечества - 23 февраля!");
               break;
           case MARCH:
               System.out.println("В марте отмечается Всемирный Женский День - 8 марта!");
               break;
       }
   }
}



public class Main {

   public static void main(String[] args) {

       HolidayReminder reminder = new HolidayReminder();
       reminder.printHolidays(Month.JANUARY);

   }

}
Output ng console:

7 января будет Рождество!
Pakitandaan: ang pag-access sa mga bagay Enumay nananatiling static, tulad noong bago ang Java 1.5. Hindi namin kailangang gumawa ng object Monthpara ma-access ang mga buwan. Kapag nagtatrabaho sa mga enumerasyon, napakahalaga na huwag kalimutan na Enumito 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 piraso ng code ay tinukoy lang namin ang mga halaga ENERO, FEBRUARY, MARCH. Gayunpaman, maaari naming palawakin ang aming enum Monthtulad nito:
public enum Month {

   JANUARY("Январь", 31),
   FEBRUARY("Февраль", 28),
   MARCH("Март", 31),
   APRIL("Апрель", 30),
   MAY("Май", 31),
   JUNE("Июнь", 30),
   JULY("Июль", 31),
   AUGUST("Август", 31),
   SEPTEMBER("Сентябрь", 30),
   OCTOBER("Октябрь", 31),
   NOVEMBER("Ноябрь", 30),
   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 nagdagdag kami ng 2 field sa amin enum- ang pangalan ng buwan at ang bilang ng mga araw, isang constructor na gumagamit ng mga field na ito, getters-setters, isang method toString(), pati na rin ang 2 static na pamamaraan. Tulad ng nakikita mo, walang mga problema dito: tulad ng sinabi namin kanina, enumito ay 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='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
Sa wakas, gusto kong irekomenda sa iyo ang isang lubhang kapaki-pakinabang na libro sa Java, 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 sa tama at karampatang paggamit ng mga tool sa wika :) Kaugnay ng aming panayam, ipinapayo ko sa iyo na bigyang-pansin ang kabanata ng aklat na nakatuon sa enum. Magkaroon ng isang produktibong pagbabasa! :)
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION