CodeGym /Java Blogu /Rastgele /Sıralama. Pratik örnekler. Yapıcılar ve yöntemler ekleme
John Squirrels
Seviye
San Francisco

Sıralama. Pratik örnekler. Yapıcılar ve yöntemler ekleme

grupta yayınlandı
MERHABA! Bugün Java'nın özel veri türlerinden biri hakkında konuşacağız: Enum("numaralandırma"nın kısaltması). Onu özel yapan nedir? Bir programda "ayları" uygulamak için neye ihtiyacımız olduğunu hayal edelim. Sıralama.  Pratik örnekler.  Yapıcılar ve yöntemler ekleme - 1 Sorunlu görünmüyor, değil mi? Sadece herhangi bir ayın hangi özelliklere sahip olduğunu belirlememiz gerekiyor. Belki de önce ayın adına ve içindeki gün sayısına ihtiyacımız var. Çözüm oldukça basit görünüyor:

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 +
               '}';
   }
}
Bütün shabang! Bir sınıfımız Month, gerekli alanlar, alıcı/ayarlayıcılar ve toString(). Tabii eklememiz gerekmedikçe equals()vehashCode()tam mutluluğa ulaşmak için :) Ama burada kavramsal bir sorunumuz var. Muhtemelen hatırladığınız gibi, OOP'nin ana avantajlarından biri, varlıkları gerçek dünyadan modellemeyi kolaylaştırmasıdır. Bir sandalye, bir araba, bir gezegen - sıradan yaşamdan tüm bu kavramlar, soyutlama yardımıyla bir programda kolayca temsil edilir. Sorun, bazı gerçek dünya varlıklarının kesinlikle sınırlı bir değer aralığına sahip olmasıdır. Bir yılda sadece 4 mevsim vardır. Bir oktavda sadece 8 nota vardır. Takvimde sadece 12 ay var. Ve Ocean's 11'den Danny Ocean'ın sadece 11 arkadaşı var (gerçi bu önemli değil :)) Önemli olan şu ki, sıradan bir Java sınıfı bu varlıkları modelleyemez ve onların doğal sınırlamalarını uygulayamaz. BizimMonthclass gerekli tüm alanlara sahiptir. Ancak başka bir programcı onu kullanırsa, hiç kimse onun tamamen çılgınca nesneler yaratmasını engelleyemez:

public class Main {

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

}
Bu, kodumuzda görünürse, suçluyu bulmak kolay olmayacaktır! Bir yandan, nesneleri yaratan programcı, sınıfın Month"yıldaki ay" anlamına geldiğini anlayabilir ve böyle saçma sapan şeyler yazmayabilir. Öte yandan, programcı yalnızca sınıf tasarımcısının sağladığı yeteneklerden yararlanmaktadır. Keyfi olarak gün isimleri ve sayıları atamak mümkün mü? Bizde tam olarak bu var. Peki bu durumda ne yapmalıyız? Dürüst olmak gerekirse, Java 1.5 yayınlanmadan önce programcıların yaratıcı olması gerekiyordu :) O günlerde şöyle yapılar oluşturuyorlardı:

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 +
               '}';
   }
}
Burada örneği kısaltmak için ay sayısını on ikiden üçe indirdik. Bu tür tasarımlar sorunu çözmeyi mümkün kıldı. Nesne oluşturma yeteneği, özel bir oluşturucuyla sınırlıydı:

private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Sınıfı kullanan programcılar basitçe nesneler yaratamazlardı Month. Sınıf geliştiricisi tarafından sağlanan son statik nesneleri kullanmaları gerekiyordu. Örneğin, bunun gibi:

public class Main {

   public static void main(String[] args) {

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

}
Ancak Java geliştiricileri mevcut soruna dikkat çekti. Elbette, programcıların dilde mevcut araçları kullanarak bir çözüm bulması harika, ancak bu çok kolay görünmüyor! Acemiler için bile bariz bir çözüme ihtiyaç vardı. Ve böylece EnumJava'da ortaya çıktı. Temel olarak, Enumsınırlı sayıda nesne değeri sağlayan bir Java sınıfıdır. İşte nasıl göründüğü:

public enum Month {
  
   JANUARY,
   FEBRUARY,
   MARCH
}
Tanımda bunun Enumbir Java sınıfı olduğunu belirtmiştik ama bu gerçekten doğru mu? Evet ve hatta bunu doğrulayabiliriz. Örneğin, numaralandırmamızı Monthbaşka bir sınıfı miras almayı deneyin:

public abstract class AbstractMonth {
}

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

   JANUARY,
   FEBRUARY,
   MARCH
}
Bu neden oluyor? Yazdığımızda:

public enum Month
derleyici bu ifadeyi aşağıdaki koda dönüştürür:

public Class Month extends Enum
Bildiğiniz gibi, Java çoklu kalıtımı desteklemez. Bu nedenle miras alamayız AbstractMonth. Bu yeni yapı nasıl Enumkullanılabilir? Ve alanlarla eski yapıdan ne farkı var static final? Örnek olarak, eski yapı, kendi değer kümemizi ifadelerde kullanmamıza izin vermiyordu switch. Bize her ay kutlanan tatilleri hatırlatacak bir program oluşturmak istediğimizi hayal edin:

public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           // Error!
           case JANUARY:
       }
   }
}
Gördüğünüz gibi derleyici burada bir hata veriyor. Ancak enumJava 1.5'te göründüğünde, her şey çok daha basit hale geldi:

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);

   }

}
Konsol çıktısı:

New Year's Day is January 1st!
EnumJava 1.5'ten önce olduğu gibi nesnelere erişimin statik kaldığını unutmayın . MonthAylara erişmek için bir nesne oluşturmamıza gerek yok . EnumNumaralandırmalarla çalışırken, bunun tam teşekküllü bir sınıf olduğunu unutmamak çok önemlidir . Bu, gerekirse yapıcıları ve yöntemleri içinde tanımlayabileceğiniz anlamına gelir. Örneğin, önceki kod parçasında basitçe şu değerleri belirledik: OCAK, ŞUBAT, MART. MonthAncak listemizi şu şekilde genişletebiliriz :

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 +
               '}';
   }
}
enumBurada 2 alanımızı (ayın adı ve gün sayısı), bu alanları kullanan bir yapıcı, alıcı/ayarlayıcılar, yöntem toString()ve 2 statik yöntem verdik . Gördüğünüz gibi, bununla ilgili herhangi bir sorun yoktu. Yine, Enumgerçekten tam teşekküllü bir sınıftır:

import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

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

   }

}
Konsol çıktısı:

[Month{name='June', daysCount=30}, Month{name='July', daysCount=31}, Month{name='August', daysCount=31}]
Son olarak, son derece kullanışlı bir Java kitabı olan Joshua Bloch'un "Effective Java" adlı kitabını önermek istiyorum . Sıralama.  Pratik örnekler.  Yapıcılar ve yöntemler ekleme - 3Yazar, Java'nın yaratıcılarından biridir, bu nedenle, dilin araçlarını nasıl doğru ve yetkin bir şekilde kullanacağınız konusunda onun tavsiyesine kesinlikle güvenebilirsiniz :) Dersimizle ilgili olarak, kitabın 'daki bölümüne özellikle dikkat etmenizi tavsiye ederim Enum. İyi okumalar! :)
Yorumlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION