CodeGym /Java Blog /Willekeurig /Opsomming. Praktische voorbeelden. Constructors en method...
John Squirrels
Niveau 41
San Francisco

Opsomming. Praktische voorbeelden. Constructors en methoden toevoegen

Gepubliceerd in de groep Willekeurig
Hoi! Vandaag zullen we het hebben over een van de speciale gegevenstypen van Java: Enum(afkorting van "enumeration"). Wat maakt het speciaal? Laten we ons eens voorstellen wat we nodig hebben om "maanden" in een programma te implementeren. Opsomming.  Praktische voorbeelden.  Constructors en methoden toevoegen - 1 Lijkt niet problematisch, toch? We hoeven alleen maar te bepalen welke eigenschappen een maand heeft. Misschien hebben we eerst de naam van de maand nodig en het aantal dagen erin. De oplossing ziet er vrij simpel uit:

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 +
               '}';
   }
}
De hele shabang! We hebben een Monthklasse, de vereiste velden, getter/setters en toString(). Tenzij we natuurlijk en moeten equals()toevoegenhashCode()om volledig geluk te bereiken :) Maar hier hebben we een conceptueel probleem. Zoals u zich waarschijnlijk herinnert, is een van de belangrijkste voordelen van OOP dat het gemakkelijk is om entiteiten uit de echte wereld te modelleren. Een stoel, een auto, een planeet - al deze concepten uit het gewone leven kunnen met behulp van abstractie gemakkelijk in een programma worden weergegeven. Het probleem is dat sommige real-world entiteiten een strikt beperkt waardenbereik hebben. Er zijn maar 4 seizoenen in een jaar. Er zijn slechts 8 noten in een octaaf. De kalender heeft slechts 12 maanden. En Danny Ocean van Ocean's 11 heeft slechts 11 vrienden (hoewel dit niet uitmaakt :)) Wat er wel toe doet, is dat een gewone Java-klasse niet in staat is om deze entiteiten te modelleren en hun natuurlijke beperkingen af ​​te dwingen. OnsMonthclass heeft alle verplichte velden. Maar als een andere programmeur het gebruikt, kan niemand hem of haar ervan weerhouden totaal gestoorde objecten te maken:

public class Main {

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

}
Als dit in onze code voorkomt, zal het niet eenvoudig zijn om de boosdoener te vinden! Aan de ene kant kan de programmeur die de objecten maakt zich realiseren dat de Monthklasse "maand in een jaar" betekent en dergelijke onzin niet schrijven. Aan de andere kant profiteert de programmeur alleen van de mogelijkheden die de klassenontwerper heeft verstrekt. Is het mogelijk om willekeurige namen en aantallen dagen toe te kennen? Dat is precies wat we hebben. Wat moeten we dan doen in deze situatie? Eerlijk gezegd, voordat Java 1.5 werd uitgebracht, moesten programmeurs creatief worden :) In die tijd creëerden ze structuren zoals deze:

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 +
               '}';
   }
}
Hier hebben we het aantal maanden teruggebracht van twaalf naar drie om het voorbeeld korter te maken. Dergelijke ontwerpen maakten het mogelijk om het probleem op te lossen. De mogelijkheid om objecten te maken was beperkt tot een privéconstructeur:

private Month(String name, int daysCount) {
       this.name = name;
       this.daysCount = daysCount;
   }
Programmeurs die de klasse gebruikten, konden niet zomaar Monthobjecten maken. Ze moesten de laatste statische objecten gebruiken die door de klassenontwikkelaar waren aangeleverd. Bijvoorbeeld als volgt:

public class Main {

   public static void main(String[] args) {

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

}
Maar Java-ontwikkelaars vestigden de aandacht op het bestaande probleem. Het is natuurlijk geweldig dat programmeurs een oplossing hebben kunnen bedenken met behulp van de tools die beschikbaar zijn in de taal, maar het ziet er niet zo gemakkelijk uit! Er was een voor de hand liggende oplossing nodig, zelfs voor beginners. En zo Enumverscheen in Java. Kortom, Enumis een Java-klasse die een beperkte set objectwaarden biedt. Zo ziet het eruit:

public enum Month {
  
   JANUARY,
   FEBRUARY,
   MARCH
}
In de definitie hebben we aangegeven dat dit Enumeen Java-klasse is, maar is dat ook echt zo? Ja, en we kunnen het zelfs verifiëren. Probeer bijvoorbeeld onze Monthenum een ​​andere klasse te laten erven:

public abstract class AbstractMonth {
}

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

   JANUARY,
   FEBRUARY,
   MARCH
}
Waarom gebeurt dat? Als we schrijven:

public enum Month
de compiler zet deze instructie om in de volgende code:

public Class Month extends Enum
Zoals u al weet, ondersteunt Java geen meervoudige overerving. Daarom kunnen we niet erven AbstractMonth. Hoe kan deze nieuwe constructie, Enum, worden gebruikt? En hoe verschilt het van de oude constructie met static finalvelden? Welnu, de oude constructie stond ons bijvoorbeeld niet toe om onze eigen reeks waarden in switchuitspraken te gebruiken. Stel je voor dat we een programma willen maken dat ons herinnert aan de feestdagen die elke maand worden gevierd:

public class HolidayReminder {

   public void printHolidays(Month month) {

       switch (month) {

           // Error!
           case JANUARY:
       }
   }
}
Zoals u kunt zien, genereert de compiler hier een fout. Maar eenmaal enumverschenen in Java 1.5, werd alles veel eenvoudiger:

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

   }

}
Console-uitvoer:

New Year's Day is January 1st!
Merk op dat de toegang tot Enumobjecten statisch bleef, net als vóór Java 1.5. We hoeven geen Monthobject te maken om toegang te krijgen tot de maanden. Bij het werken met opsommingen is het erg belangrijk om niet te vergeten dat dit Enumeen volwaardige klas is. Dit betekent dat je er, indien nodig, constructors en methoden in kunt definiëren. In het vorige codefragment hebben we bijvoorbeeld simpelweg de waarden opgegeven: JANUARI, FEBRUARI, MAART. We kunnen onze opsomming echter Monthals volgt uitbreiden:

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 +
               '}';
   }
}
Hier gaven we onze enum2 velden (de naam van de maand en het aantal dagen), een constructor die deze velden gebruikt, getter/setters, de toString()methode en 2 statische methoden. Zoals u kunt zien, waren hier geen problemen mee. Nogmaals, Enumis echt een volwaardige klasse:

import java.util.Arrays;

public class Main {

   public static void main(String[] args) {

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

   }

}
Console-uitvoer:

[Month{name='June', daysCount=30}, Month{name='July', daysCount=31}, Month{name='August', daysCount=31}]
Tot slot wil ik een uiterst nuttig Java-boek aanbevelen, namelijk "Effective Java" van Joshua Bloch . Opsomming.  Praktische voorbeelden.  Constructors en methoden toevoegen - 3De auteur is een van de makers van Java, dus je kunt zeker vertrouwen op zijn advies over hoe je de taalhulpmiddelen correct en competent kunt gebruiken :) Met betrekking tot onze les raad ik je aan om speciale aandacht te besteden aan het hoofdstuk in het boek over Enum. Veel leesplezier! :)
Opmerkingen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION