JavaRush /Blog Java /Random-MS /Enum di Jawa. Contoh praktikal. Menambah Pembina dan Kaed...

Enum di Jawa. Contoh praktikal. Menambah Pembina dan Kaedah

Diterbitkan dalam kumpulan
hello! Hari ini kita akan bercakap tentang jenis data khas dalam Java - Enum(singkatan untuk penghitungan). Apakah ciri mereka? Bayangkan kita perlu melaksanakan berbulan-bulan dalam program tersebut. Enum.  Contoh praktikal.  Menambah pembina dan kaedah - 1Nampaknya, apa masalahnya? Anda hanya perlu menentukan hartanah yang ada pada setiap bulan. Mungkin kita memerlukan, pertama sekali, nama bulan dan bilangan hari di dalamnya. Penyelesaian kepada masalah kelihatan agak mudah:
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 +
               '}';
   }
}
Tolong set penuh! Kami mempunyai kelas Month, medan yang diperlukan, getters-setter, toString(). Melainkan equals()anda hashCode()perlu menambahnya untuk kebahagiaan yang lengkap :) Walau bagaimanapun, kami mempunyai masalah konsep. Seperti yang anda ingat, salah satu kelebihan utama OOP ialah ia memudahkan untuk memodelkan entiti dunia sebenar. Kerusi, kereta, planet - semua konsep ini dari kehidupan seharian mudah diwakili dalam program menggunakan abstraksi. Masalahnya ialah sesetengah entiti dalam dunia nyata mempunyai julat makna yang sangat terhad. Hanya ada 4 musim dalam setahun. Terdapat hanya 7 nota dalam muzik. Hanya ada 12 bulan dalam kalendar. Ocean hanya mempunyai 11 rakan (walaupun ini boleh dibahaskan :)) Dalam erti kata lain, kelas Java biasa tidak dapat memodelkan entiti ini dan menghormati kekangan semula jadi mereka. Kelas kami Monthmempunyai semua bidang yang diperlukan. Tetapi jika pengaturcara lain menggunakannya, tiada siapa yang akan menghalangnya daripada mencipta objek gila sepenuhnya:
public class Main {

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

}
Jika ini muncul dalam program, ia tidak akan mudah untuk mencari pelakunya! Di satu pihak, pengaturcara yang mencipta objek mungkin memahami bahawa kelas itu Monthbermaksud "bulan dalam setahun" dan tidak menulis perkara yang tidak masuk akal. Sebaliknya, dia hanya memanfaatkan peluang yang diberikan oleh pereka kelas kepadanya. Bolehkah saya menetapkan sebarang nama dan bilangan hari? Dia melantiknya. Apa yang perlu dilakukan dalam keadaan sedemikian? Sebelum keluaran bahasa Java versi 1.5, pengaturcara terpaksa, terus terang, keluar daripadanya :) Pada masa itu, mereka mencipta binaan berikut:
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 +
               '}';
   }
}
Di sini kami telah mempermudahkan bilangan bulan kepada tiga dan bukannya dua belas untuk memastikan contoh lebih pendek. Reka bentuk sedemikian memungkinkan untuk menyelesaikan masalah. Pilihan untuk objek yang dicipta dihadkan oleh pembina peribadi:
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Pengaturcara yang menggunakan kelas tidak boleh mencipta Month. Mereka terpaksa menggunakan objek statik terakhir yang disediakan oleh pembangun kelas. Ia kelihatan seperti ini:
public class Main {

   public static void main(String[] args) {

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

}
Walau bagaimanapun, pembangun Java telah menyedari masalah yang sedia ada. Sudah tentu, sangat bagus bahawa pengaturcara dapat menghasilkan penyelesaian menggunakan alat yang tersedia dalam bahasa, tetapi ia tidak kelihatan begitu mudah! Penyelesaian yang jelas diperlukan, boleh diakses walaupun kepada pemula. Beginilah caranya muncul di Jawa Enum. Pada asasnya, Enumia adalah kelas Java yang menyediakan set terhad objek nilai. Inilah rupanya:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
Dalam definisi, kami menunjukkan bahawa Enumini adalah kelas Java, tetapi adakah ini benar? Ya, dan kami juga boleh menyemaknya. Cuba, sebagai contoh, mewarisi kelas kami enum Monthdari beberapa kelas lain:
public abstract class AbstractMonth {
}

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

   JANUARY,
   FEBRUARY,
   MARCH
}
Kenapa ini terjadi? Apabila kita menulis kepada program:
public enum Month
Pengkompil menukar arahan ini menjadi kod seperti ini:
public Class Month extends Enum
Seperti yang anda sedia maklum, warisan berbilang tidak dibenarkan di Jawa. Oleh itu, AbstractMonthkami tidak boleh mewarisi. Bagaimanakah reka bentuk baharu ini boleh Enumdigunakan? Dan bagaimana ia berbeza daripada reka bentuk lama dengan static finalbidang? Nah, sebagai contoh, reka bentuk lama tidak membenarkan kami menggunakan set nilai kami sendiri dalam switch-ungkapan. Bayangkan kita ingin membuat program yang akan mengingatkan kita tentang cuti yang disambut pada bulan ini:
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
Di sini, seperti yang anda lihat, pengkompil melemparkan ralat. Tetapi selepas Java 1.5 muncul enum, semuanya menjadi lebih mudah:
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 konsol:

7 января будет Рождество!
Sila ambil perhatian: akses kepada objek Enumkekal statik, seperti sebelum Java 1.5. Kami tidak perlu mencipta objek Monthuntuk mengakses bulan. Apabila bekerja dengan penghitungan, adalah sangat penting untuk tidak lupa bahawa Enumini adalah kelas yang lengkap. Ini bermakna, jika perlu, anda boleh menentukan pembina dan kaedah di dalamnya. Sebagai contoh, dalam sekeping kod sebelumnya, kami hanya menentukan nilai JANUARI, FEBRUARI, MAC. Walau bagaimanapun, kita boleh mengembangkannya enum Monthseperti ini:
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 +
               '}';
   }
}
Di sini kami telah menambah 2 medan kepada kami enum- nama bulan dan bilangan hari, pembina menggunakan medan ini, getters-setters, method toString(), serta 2 kaedah statik. Seperti yang anda lihat, tidak ada masalah dengan ini: seperti yang kami katakan sebelum ini, enumini adalah kelas yang lengkap:
import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

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

   }

}
Output konsol:

[Month{name='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
Akhir sekali, saya ingin mengesyorkan anda satu buku yang sangat berguna tentang Java, iaitu "Java Berkesan" oleh Joshua Bloch . Enum.  Contoh praktikal.  Menambah pembina dan kaedah - 3Penulis adalah salah seorang pencipta Java, jadi anda pasti boleh mempercayai nasihatnya tentang penggunaan alat bahasa yang betul dan cekap :) Sehubungan dengan kuliah kami, saya menasihati anda untuk memberi perhatian khusus kepada bab buku yang didedikasikan untuk enum. Selamat membaca yang produktif! :)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION