JavaRush /Java Blogu /Random-AZ /Java-da enum. Praktik nümunələr. Konstruktorların və Meto...

Java-da enum. Praktik nümunələr. Konstruktorların və Metodların əlavə edilməsi

Qrupda dərc edilmişdir
Salam! Bu gün biz Java-da xüsusi bir məlumat növü haqqında danışacağıq - Enum(sadalamaq üçün qısa). Onların xüsusiyyəti nədir? Təsəvvür edək ki, proqramda ayları həyata keçirmək lazımdır. Enum.  Praktik nümunələr.  Konstruktorların və metodların əlavə edilməsi - 1Görünür, problem nədir? Sadəcə hər ayın hansı xassələrə malik olduğunu müəyyən etmək lazımdır. Bəlkə də, ilk növbədə, ayın adı və içindəki günlərin sayı lazımdır. Problemin həlli olduqca sadə görünür:
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 +
               '}';
   }
}
Zəhmət olmasa tam dəst! Bizdə bir sinif var Month, lazımlı sahələr, alıcı-ayarlayıcılar, toString(). equals()Tam xoşbəxtlik üçün əlavə etmək lazım olmadıqca hashCode():) Ancaq konseptual problemimiz var. Yadınızdadırsa, OOP-un əsas üstünlüklərindən biri odur ki, o, real dünya obyektlərini modelləşdirməyi asanlaşdırır. Kreslo, maşın, planet - gündəlik həyatdan bütün bu anlayışları abstraksiyadan istifadə edərək proqramda təmsil etmək asandır. Problem ondadır ki, real dünyadakı bəzi varlıqlar ciddi şəkildə məhdud məna dairəsinə malikdir. Bir ildə cəmi 4 fəsil var. Musiqidə cəmi 7 not var. Təqvimdə cəmi 12 ay var. Okeanın cəmi 11 dostu var (baxmayaraq ki, bu mübahisəlidir :)) Başqa sözlə, adi Java sinfi bu obyektləri modelləşdirmək və onların təbii məhdudiyyətlərinə hörmət etmək iqtidarında deyil. Sinifimizdə Monthbütün lazımi sahələr var. Ancaq başqa bir proqramçı istifadə edərsə, heç kim ona tamamilə dəli obyektlər yaratmağa mane olmayacaq:
public class Main {

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

}
Bu proqramda görünsə, günahkarı tapmaq asan olmayacaq! Bir tərəfdən, obyektləri yaradan proqramçı sinifin Month“ilin ayı” demək olduğunu başa düşə və belə cəfəngiyyat yazmaya bilərdi. Digər tərəfdən, o, sadəcə olaraq sinif dizaynerinin ona verdiyi imkanlardan istifadə edirdi. İstənilən ad və günlərin sayını təyin edə bilərəmmi? O təyin etdi. Belə bir vəziyyətdə nə etməli? Java dilinin 1.5 versiyası buraxılmazdan əvvəl proqramçılar, açığını desəm, ondan çıxmalı idilər :) O günlərdə onlar aşağıdakı konstruksiyalar yaratmışdılar:
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 +
               '}';
   }
}
Burada nümunəni daha qısa tutmaq üçün ayların sayını on iki əvəzinə üçə qədər sadələşdirdik. Bu cür dizaynlar problemi həll etməyə imkan verdi. Yaradılmış obyektlər üçün seçimlər xüsusi konstruktor tərəfindən məhdudlaşdırıldı:
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Sinifdən istifadə edən proqramçılar sadəcə yarada bilməzlər Month. Onlar sinif tərtibatçısının təqdim etdiyi son statik obyektlərdən istifadə etməyə məcbur oldular. Bu kimi bir şey görünürdü:
public class Main {

   public static void main(String[] args) {

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

}
Bununla belə, Java tərtibatçıları mövcud problemi qeyd ediblər. Əlbətdə ki, proqramçıların dildə mövcud olan vasitələrdən istifadə edərək həll yolu tapa bilmələri çox gözəldir, lakin bu o qədər də sadə görünmür! Hətta yeni başlayanlar üçün əlçatan olan açıq bir həll lazım idi. Java-da belə ortaya çıxdı Enum. Əslində, Enumbu, məhdud dəyər obyektləri dəstini təmin edən Java sinfidir. Göründüyü kimi:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
Tərifdə Enumbunun Java sinfi olduğunu qeyd etdik, amma bu həqiqətən belədirmi? Bəli, hətta yoxlaya bilərik. Məsələn, bizimkini enum Monthbaşqa bir sinifdən miras almağa çalışın:
public abstract class AbstractMonth {
}

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

   JANUARY,
   FEBRUARY,
   MARCH
}
Bu niyə baş verir? Proqrama yazanda:
public enum Month
Kompilyator bu əmri aşağıdakı kimi koda çevirir:
public Class Month extends Enum
Artıq bildiyiniz kimi, Java-da çoxlu varisliyə icazə verilmir. Ona görə də AbstractMonthmiras ala bilmədik. Bu yeni dizayndan necə Enumistifadə etmək olar? Və sahələri olan köhnə dizayndan nə ilə fərqlənir static final? Yaxşı, məsələn, köhnə dizayn bizə öz dəyərlər dəstimizdən switchifadələrdə istifadə etməyə imkan vermədi. Təsəvvür edin ki, bu ay hansı bayramların qeyd olunduğunu bizə xatırladacaq bir proqram yaratmaq istəyirik:
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
Burada, gördüyünüz kimi, kompilyator xəta atır. Ancaq Java 1.5 ortaya çıxdıqdan sonra enumhər şey daha sadə oldu:
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);

   }

}
Konsol çıxışı:

7 января будет Рождество!
Nəzərə alın: obyektlərə giriş EnumJava 1.5-dən əvvəl olduğu kimi statik olaraq qalır. Aylara daxil olmaq üçün obyekt yaratmağa ehtiyacımız yoxdur Month. EnumSadalamalarla işləyərkən bunun tam hüquqlu bir sinif olduğunu unutmamaq çox vacibdir . Bu o deməkdir ki, lazım gələrsə, onda konstruktorlar və metodlar müəyyən edə bilərsiniz. Məsələn, əvvəlki kod parçasında biz sadəcə YANVAR, FEVRAL, MART dəyərlərini qeyd etdik. enum MonthBununla belə, özümüzü belə genişləndirə bilərik :
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 +
               '}';
   }
}
Burada özümüzə 2 sahə əlavə etdik enum- ayın adı və günlərin sayı, bu sahələrdən istifadə edən konstruktor, getters-setter, metod toString(), həmçinin 2 statik metod. Gördüyünüz kimi, bununla bağlı heç bir problem yox idi: əvvəllər dediyimiz kimi, enumbu tam hüquqlu bir sinifdir:
import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

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

   }

}
Konsol çıxışı:

[Month{name='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
Nəhayət, mən sizə Java haqqında çox faydalı bir kitabı, Coşua Blokun “Effektiv Java” kitabını tövsiyə etmək istəyirəm . Enum.  Praktik nümunələr.  Konstruktorların və metodların əlavə edilməsi - 3Müəllif Java-nın yaradıcılarından biridir, ona görə də onun dil alətlərindən düzgün və səriştəli istifadəsi ilə bağlı məsləhətlərinə mütləq etibar edə bilərsiniz :) Mühazirəmizlə əlaqədar olaraq kitabın -a həsr olunmuş fəslinə xüsusi diqqət yetirməyi məsləhət görürəm enum. Məhsuldar oxuyun! :)
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION