JavaRush /Java Blog /Random-ID /Enum di Jawa. Contoh praktis. Menambahkan Konstruktor dan...

Enum di Jawa. Contoh praktis. Menambahkan Konstruktor dan Metode

Dipublikasikan di grup Random-ID
Halo! Hari ini kita akan berbicara tentang tipe data khusus di Java - Enum(kependekan dari enumerasi). Apa fitur mereka? Bayangkan kita perlu menerapkan program berbulan-bulan. enum.  Contoh praktis.  Menambahkan konstruktor dan metode - 1Tampaknya, apa masalahnya? Anda hanya perlu menentukan properti apa saja yang dimiliki suatu bulan. Mungkin pertama-tama kita memerlukan nama bulan dan jumlah hari di dalamnya. Solusi untuk masalah ini terlihat cukup sederhana:
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 lengkapnya! Kami memiliki kelas Month, bidang yang diperlukan, pengambil-penyetel, toString(). Kecuali equals()Anda hashCode()perlu menambahkannya untuk kebahagiaan yang utuh :) Namun, kami memiliki masalah konseptual. Seperti yang mungkin Anda ingat, salah satu keuntungan utama OOP adalah memudahkan pemodelan entitas dunia nyata. Kursi, mobil, planet - semua konsep kehidupan sehari-hari ini mudah direpresentasikan dalam program menggunakan abstraksi. Masalahnya adalah beberapa entitas di dunia nyata memiliki jangkauan makna yang sangat terbatas. Hanya ada 4 musim dalam setahun. Hanya ada 7 nada dalam musik. Hanya ada 12 bulan dalam kalender. Ocean hanya memiliki 11 teman (walaupun hal ini masih bisa diperdebatkan :)) Dengan kata lain, kelas Java reguler tidak dapat memodelkan entitas ini dan menghormati batasan alaminya. Kelas kami Monthmemiliki semua bidang yang diperlukan. Tetapi jika programmer lain menggunakannya, tidak ada yang akan menghentikannya membuat objek yang benar-benar gila:
public class Main {

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

}
Jika ini muncul di program, tidak akan mudah menemukan pelakunya! Di satu sisi, programmer yang membuat objek dapat memahami bahwa kelas tersebut Monthberarti “bulan dalam setahun” dan tidak menulis omong kosong seperti itu. Di sisi lain, dia hanya memanfaatkan peluang yang diberikan desainer kelas kepadanya. Bisakah saya menetapkan nama dan jumlah hari? Dia menunjuknya. Apa yang harus dilakukan dalam situasi seperti ini? Sebelum rilis bahasa Java versi 1.5, sejujurnya programmer harus keluar darinya :) Pada masa itu, mereka membuat konstruksi 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 menyederhanakan jumlah bulan menjadi tiga, bukan dua belas, agar contohnya lebih singkat. Desain seperti itu memungkinkan pemecahan masalah. Opsi untuk objek yang dibuat dibatasi oleh konstruktor pribadi:
private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Pemrogram yang menggunakan kelas tersebut tidak bisa begitu saja membuat Month. Mereka terpaksa menggunakan objek statis terakhir yang disediakan oleh pengembang kelas. Itu terlihat seperti ini:
public class Main {

   public static void main(String[] args) {

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

}
Namun, pengembang Java menyadari adanya masalah. Tentu saja, sangat bagus bahwa pemrogram dapat menemukan solusi menggunakan alat yang tersedia dalam bahasa tersebut, tetapi tampaknya tidak sesederhana itu! Diperlukan solusi yang jelas, dapat diakses bahkan oleh pemula. Ini adalah bagaimana muncul di Jawa Enum. Pada dasarnya, Enumini adalah kelas Java yang menyediakan sekumpulan objek nilai terbatas. Berikut tampilannya:
public enum Month {

   JANUARY,
   FEBRUARY,
   MARCH
}
Dalam definisinya, kami menunjukkan bahwa Enumini adalah kelas Java, tetapi apakah ini benar? Ya, dan kami bahkan dapat memeriksanya. Coba, misalnya, mewarisi kelas kami enum Monthdari kelas lain:
public abstract class AbstractMonth {
}

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

   JANUARY,
   FEBRUARY,
   MARCH
}
Mengapa ini terjadi? Saat kita menulis ke suatu program:
public enum Month
Kompiler mengubah perintah ini menjadi kode seperti ini:
public Class Month extends Enum
Seperti yang sudah Anda ketahui, pewarisan berganda tidak diperbolehkan di Java. Oleh karena itu, AbstractMonthkami tidak dapat mewarisinya. Bagaimana desain baru ini dapat Enumdigunakan? Dan apa bedanya dengan desain lama yang static finalberbidang? Misalnya, desain lama tidak memungkinkan kita menggunakan kumpulan nilai kita sendiri dalam switch-ekspresi. Bayangkan kita ingin membuat program yang mengingatkan kita hari libur apa saja yang dirayakan bulan ini:
public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           //error!
           case JANUARY:
       }
   }
}
Di sini, seperti yang Anda lihat, kompiler membuat kesalahan. Namun setelah Java 1.5 muncul enum, semuanya menjadi lebih sederhana:
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);

   }

}
Keluaran konsol:

7 января будет Рождество!
Harap diperhatikan: akses ke objek Enumtetap statis, seperti sebelum Java 1.5. Kita tidak perlu membuat objek Monthuntuk mengakses bulan. Saat bekerja dengan enumerasi, sangat penting untuk tidak lupa bahwa Enumini adalah kelas yang lengkap. Artinya, jika perlu, Anda dapat mendefinisikan konstruktor dan metode di dalamnya. Misalnya pada potongan kode sebelumnya kita cukup menentukan nilai JANUARI, FEBRUARI, MARET. Namun, kami dapat memperluasnya 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 menambahkan 2 bidang ke bidang kami enum- nama bulan dan jumlah hari, konstruktor yang menggunakan bidang ini, pengambil-penyetel, metode toString(), serta 2 metode statis. Seperti yang Anda lihat, tidak ada masalah dengan ini: seperti yang kami katakan sebelumnya, 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()));

   }

}
Keluaran konsol:

[Month{name='Июнь', daysCount=30}, Month{name='Июль', daysCount=31}, Month{name='Август', daysCount=31}]
Terakhir, saya ingin merekomendasikan Anda satu buku yang sangat berguna tentang Java, yaitu “Effective Java” oleh Joshua Bloch . enum.  Contoh praktis.  Menambahkan konstruktor dan metode - 3Penulisnya adalah salah satu pencipta Java, jadi Anda pasti dapat mempercayai nasihatnya tentang penggunaan alat bahasa yang benar dan kompeten :) Sehubungan dengan kuliah kami, saya menyarankan Anda untuk memberikan perhatian khusus pada bab buku yang didedikasikan untuk enum. Selamat membaca! :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION