JavaRush /Java блогу /Random-KY /Javaдагы Enum. Практикалык мисалдар. Конструкторлорду жан...

Javaдагы Enum. Практикалык мисалдар. Конструкторлорду жана методдорду кошуу

Группада жарыяланган
Салам! Бүгүн биз Java-дагы атайын берorштер түрү жөнүндө сөз кылабыз - Enum(санак үчүн кыскача). Алардын өзгөчөлүгү эмнеде? Программада айларды ишке ашыруу керек деп элестетип көрөлү. Enum.  Практикалык мисалдар.  Конструкторлорду жана методдорду кошуу - 1Көрсө, көйгөй эмнеде? Сиз жөн гана ар бир айдын кандай касиеттери бар экенин аныктоо керек. Балким, бизге, биринчи кезекте, айдын аты жана андагы күндөрдүн саны керек. Маселени чечүү абдан жөнөкөй көрүнөт:
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 +
               '}';
   }
}
Сураныч, толук комплект! Бизде класс Month, керектуу талаалар, гетер-сетерлор, toString(). equals()Толук бакыт үчүн аны кошуунун кереги болбосо hashCode():) Бирок, бизде концептуалдык көйгөй бар. Эсиңизде болсо керек, OOPтин негизги артыкчылыктарынын бири - бул реалдуу дүйнө an objectилерин моделдештирүү оңой. Кресло, машина, планета - бул күнүмдүк турмуштан алынган бардык түшүнүктөрдү абстракцияны колдонуу менен программада көрсөтүү оңой. Маселе чыныгы дүйнөдөгү кээ бир an objectилердин маанисинин чектелүү диапазонунда. Бир жылда 4 гана мезгил бар. Музыкада болгону 7 нота бар. Календарда болгону 12 ай бар. Океандын 11 гана досу бар (бирок бул талаштуу :)) Башкача айтканда, кадимки Java классы бул an objectтерди моделдей алbyte жана алардын табигый чектөөлөрүн сыйлай алbyte. Биздин класста Monthбардык керектүү талаалар бар. Бирок аны башка программист колдонсо, эч ким ага таптакыр жинди an objectтерди түзүүгө тоскоол болбойт:
public class Main {

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

}
Бул программада пайда болсо, күнөөлүүнү табуу оңой болбойт! Бир жагынан, an objectтерди жараткан программист класс Month"жыл айы" дегенди түшүндүрүп, мындай куру сөздү жазбай эле түшүнсө болмок. Экинчи жагынан, ал класстын дизайнери ага берген мүмкүнчүлүктөрдү жөн эле пайдаланып жаткан. Мен кандайдыр бир аттарды жана күндөрдүн санын дайындай аламбы? Ал дайындады. Мындай кырдаалда эмне кылуу керек? Java тorнин 1.5 versionсы чыкканга чейин, программисттер, ачык айтканда, андан чыгып кетиши керек болчу :) Ошол күндөрү алар төмөнкү конструкцияларды түзүшкөн:
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 +
               '}';
   }
}
Бул жерде мисалды кыскартуу үчүн айлардын санын он экиге эмес, үчкө чейин жөнөкөйлөттүк. Мындай конструкциялар маселени чечүүгө мүмкүндүк берди. Түзүлгөн an objectилердин параметрлери жеке конструктор тарабынан чектелген:
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Классты колдонгон программисттер жөн эле түзө алышпайт Month. Алар класстын иштеп чыгуучусу тарабынан берилген акыркы статикалык an objectтерди колдонууга аргасыз болушкан. Ал мындай көрүндү:
public class Main {

   public static void main(String[] args) {

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

}
Бирок, Java иштеп чыгуучулары бар көйгөйдү байкашкан. Албетте, программисттер тилде жеткorктүү куралдарды колдонуу менен бир чечимге келе алганы абдан жакшы, бирок бул анчалык деле жөнөкөй көрүнбөйт! Ачык чечим керек болчу, ал тургай үйрөнчүктөр үчүн жеткorктүү. Бул Java менен пайда болгон Enum. Негизинен Enumбул Java классы, ал баалуу an objectтердин чектелген топтомун камсыз кылат. Ал кандай көрүнөт:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
Аныктамада биз Enumбул Java классы экенин көрсөттүк, бирок бул чын эле ушундайбы? Ооба, биз аны текшере алабыз. Мисалы, биздин классты enum Monthбашка класстан мурастап көрүңүз:
public abstract class AbstractMonth {
}

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

   JANUARY,
   FEBRUARY,
   MARCH
}
Эмне үчүн бул болуп жатат? Биз программага жазганда:
public enum Month
Компилятор бул буйрукту төмөнкүдөй codeго айлантат:
public Class Month extends Enum
Белгилүү болгондой, Javaда бир нече мураска жол берилбейт. Ошондуктан, AbstractMonthбиз мурас ала алган жокпуз. Бул жаңы дизайнды кантип Enumколдонсо болот? Ал эми талаалары бар эски дизайндан эмнеси менен айырмаланат static final? Ооба, мисалы, эски дизайн -экспрессияларда өз баалуулуктарыбызды колдонууга мүмкүнчүлүк берген жок switch. Элестеткиле, биз ушул айда кандай майрамдар белгиленерин эскерте турган программа түзгүбүз келет:
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
Бул жерде, сиз көрүп тургандай, компилятор ката кетирет. Бирок Java 1.5 пайда болгондон кийин enum, баары жөнөкөй болуп калды:
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);

   }

}
Консолдук чыгаруу:

7 января будет Рождество!
Көңүл буруңуз: an objectтерге кирүү EnumJava 1.5ке чейинкидей эле статикалык бойдон калууда. Айларга кирүү үчүн an objectти түзүүнүн кереги жок Month. EnumСанаптар менен иштөөдө бул толук кандуу класс экенин унутпашыбыз керек . Бул, эгерде зарыл болсо, анда конструкторлорду жана методдорду аныктай аласыз дегенди билдирет. Мисалы, codeдун мурунку бөлүгүндө биз ЖАНВАРЬ, ФЕВРАЛЬ, МАРТ деген маанилерди гана көрсөткөнбүз. enum MonthБирок, биз өзүбүздү төмөнкүдөй кеңейте алабыз :
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 +
               '}';
   }
}
Бул жерде биз өзүбүзгө 2 талаа коштук enum- айдын аталышы жана күндөрдүн саны, бул талааларды колдонгон конструктор, гетер-сеттер, метод toString(), ошондой эле 2 статикалык ыкма. Көрүнүп тургандай, бул менен эч кандай көйгөйлөр болгон жок: биз жогоруда айткандай, enumбул толук кандуу класс:
import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

       System.out.println(Arrays.toString(Month.getSummerMonths()));

   }

}
Консолдук чыгаруу:

[Month{name='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
Акырында мен сизге Java боюнча өтө пайдалуу китепти сунуштагым келет, тактап айтканда, Жошуа Блохтун "Эффективдүү Java" китеби . Enum.  Практикалык мисалдар.  Конструкторлорду жана методдорду кошуу - 3Author Java программасын түзүүчүлөрдүн бири, андыктан тил куралдарын туура жана сабаттуу колдонуу боюнча анын кеңешине ишенсеңиз болот :) Биздин лекциябызга байланыштуу мен китептин enum. Жемиштүү окуу болсун! :)
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION