CodeGym /Java Blog /Acak /Enum. Contoh praktis. Menambahkan konstruktor dan metode
John Squirrels
Level 41
San Francisco

Enum. Contoh praktis. Menambahkan konstruktor dan metode

Dipublikasikan di grup Acak
Hai! Hari ini kita akan berbicara tentang salah satu tipe data khusus Java: Enum(singkatan dari "enumeration"). Apa yang membuatnya spesial? Bayangkan apa yang kita butuhkan untuk mengimplementasikan "bulan" dalam sebuah program. Enum.  Contoh praktis.  Menambahkan konstruktor dan metode - 1 Sepertinya tidak bermasalah, bukan? Kami hanya perlu menentukan properti apa yang dimiliki setiap bulan. Mungkin pertama-tama kita membutuhkan nama bulan dan jumlah hari di dalamnya. Solusinya 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 +
               '}';
   }
}
Seluruh shabang! Kami memiliki Monthkelas, bidang wajib, pengambil/penyetel, dan toString(). Kecuali, tentu saja, kita perlu menambahkan equals()danhashCode()untuk mencapai kebahagiaan sepenuhnya :) Tapi di sini kita memiliki masalah konseptual. Seperti yang mungkin Anda ingat, salah satu keuntungan utama OOP adalah memudahkan pemodelan entitas dari dunia nyata. Kursi, mobil, planet - semua konsep dari kehidupan biasa ini dengan mudah direpresentasikan dalam sebuah program dengan bantuan abstraksi. Masalahnya adalah bahwa beberapa entitas dunia nyata memiliki rentang nilai yang sangat terbatas. Hanya ada 4 musim dalam setahun. Hanya ada 8 nada dalam satu oktaf. Kalender hanya memiliki 12 bulan. Dan Danny Ocean of Ocean's 11 hanya memiliki 11 teman (walaupun ini tidak masalah :)) Yang penting adalah kelas Java biasa tidak dapat memodelkan entitas ini dan menerapkan batasan alaminya. KitaMonthkelas memiliki semua bidang yang diperlukan. Tetapi jika programmer lain menggunakannya, tidak ada yang bisa menghentikannya untuk 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 kode kita, tidak akan mudah menemukan pelakunya! Di satu sisi, programmer yang membuat objek mungkin menyadari bahwa kelas Monthberarti "bulan dalam setahun" dan tidak menulis omong kosong seperti itu. Di sisi lain, programmer hanya memanfaatkan kemampuan yang disediakan oleh desainer kelas. Apakah mungkin untuk menetapkan nama dan jumlah hari yang sewenang-wenang? Itulah tepatnya yang kami dapatkan. Lalu apa yang harus kita lakukan dalam situasi ini? Sejujurnya, sebelum Java 1.5 dirilis, programmer harus kreatif :) Pada masa itu, mereka membuat struktur seperti ini:

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("January", 31);
   public static Month FEBRUARY = new Month("February", 28);
   public static Month MARCH = new Month("March", 31);

   @Override
   public String toString() {
       return "Month{" +
               "name='" + name + '\'' +
               ", daysCount=" + daysCount +
               '}';
   }
}
Di sini kita telah memotong jumlah bulan dari dua belas menjadi tiga untuk mempersingkat contoh. Desain seperti itu memungkinkan untuk memecahkan masalah. Kemampuan untuk membuat objek terbatas pada konstruktor pribadi:

private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Pemrogram yang menggunakan kelas tidak bisa begitu saja membuat Monthobjek. Mereka harus menggunakan objek statis terakhir yang disediakan oleh pengembang kelas. Misalnya, seperti ini:

public class Main {

   public static void main(String[] args) {

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

}
Tapi, pengembang Java memperhatikan masalah yang ada. Tentu saja, sangat bagus bahwa pemrogram dapat menemukan solusi menggunakan alat yang tersedia dalam bahasa tersebut, tetapi tampaknya tidak mudah! Diperlukan solusi yang jelas, bahkan untuk pemula. Dan begitu Enummuncul di Jawa. Pada dasarnya, Enumadalah kelas Java yang menyediakan sekumpulan nilai objek yang terbatas. Begini tampilannya:

public enum Month {
  
   JANUARY,
   FEBRUARY,
   MARCH
}
Dalam definisi, kami menunjukkan bahwa itu Enumadalah kelas Java, tetapi apakah itu benar? Ya, dan kami bahkan dapat memverifikasinya. Misalnya, coba buat Monthenum kami mewarisi beberapa kelas lain:

public abstract class AbstractMonth {
}

// Error! The extends clause cannot be used with an enum
public enum Month extends AbstractMonth {

   JANUARY,
   FEBRUARY,
   MARCH
}
Mengapa itu terjadi? Ketika kita menulis:

public enum Month
kompiler mengubah pernyataan ini menjadi kode berikut:

public Class Month extends Enum
Seperti yang sudah Anda ketahui, Java tidak mendukung banyak pewarisan. Oleh karena itu, kami tidak dapat mewarisi AbstractMonth. Bagaimana konstruk baru ini, Enum, dapat digunakan? Dan apa bedanya dengan konstruksi lama dengan static finalbidang? Nah, sebagai contoh, konstruk lama tidak mengizinkan kita menggunakan kumpulan nilai kita sendiri dalam switchpernyataan. Bayangkan kita ingin membuat program yang akan mengingatkan kita pada liburan yang dirayakan setiap bulan:

public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           // Error!
           case JANUARY:
       }
   }
}
Seperti yang Anda lihat, kompiler melempar kesalahan di sini. Tapi begitu enummuncul di Java 1.5, 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("New Year's Day is January 1st!");
               break;
           case FEBRUARY:
               System.out.println("Valentine's Day is February 14th!");
               break;
           case MARCH:
               System.out.println("Saint Patrick's Day is March 17th!");
               break;
       }
   }
}


public class Main {

   public static void main(String[] args) {

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

   }

}
Keluaran konsol:

New Year's Day is January 1st!
Perhatikan bahwa akses ke Enumobjek tetap statis, sama seperti sebelum Java 1.5. Kita tidak perlu membuat Monthobjek untuk mengakses bulan. Saat bekerja dengan enum, sangat penting untuk tidak lupa bahwa ini Enumadalah kelas yang lengkap. Artinya, jika perlu, Anda dapat menentukan konstruktor dan metode di dalamnya. Misalnya, di fragmen kode sebelumnya, kami hanya menentukan nilainya: JANUARI, FEBRUARI, MARET. Namun, kami dapat memperluas Monthenum kami seperti ini:

public enum Month {

   JANUARY("January", 31),
   FEBRUARY("February", 28),
   MARCH("March", 31),
   APRIL("April", 30),
   MAY("May", 31),
   JUNE("June", 30),
   JULY("July", 31),
   AUGUST("August", 31),
   SEPTEMBER("September", 30),
   OCTOBER("October", 31),
   NOVEMBER("November", 30),
   DECEMBER("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 memberikan enum2 bidang kami (nama bulan dan jumlah hari), konstruktor yang menggunakan bidang ini, pengambil/penyetel, metode toString(), dan 2 metode statis. Seperti yang Anda lihat, tidak ada masalah dengan ini. Sekali lagi, Enumbenar-benar 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='June', daysCount=30}, Month{name='July', daysCount=31}, Month{name='August', daysCount=31}]
Terakhir, saya ingin merekomendasikan buku Java yang sangat berguna, yaitu "Java Efektif" oleh Joshua Bloch . Enum.  Contoh praktis.  Menambahkan konstruktor dan metode - 3Penulis adalah salah satu pencipta Java, jadi Anda pasti dapat mempercayai sarannya tentang cara menggunakan alat bahasa dengan benar dan kompeten :) Sehubungan dengan pelajaran kami, saya sarankan Anda memberi perhatian khusus pada bab buku tentang Enum. Selamat membaca! :)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION