ენუმერაცია ჯავაში
არის კლასი, რომლის მეშვეობითაც მარტივად ვქმნით ტიპს, მასში მხოლოდ კონსტანტების დეფინირება
ხდება, სხვა კონკურენტი ენებისგან განსხვავებით ენუმერაცია ჯავაში არის გაცილებით უფრო
დახვეწილი და ძლიერი ხელსაწყო, რადგან შესაძლებელია მეთოდების, ცვლადების და კონსტრუკტორის
დეფინირება.
მისი დეფინირება ხდება
საკვანძო სიტყვა enum-ის მეშვეობით, ეს სიტყვა კომპილატორს აცნობებს, რომ მომხმარებელი ენუმერაციას
ქმნის.
მარტივი ენუმერაციის შექმნის მაგალითი:
კონკრეტული ღირებულების
გამოყენება შესაძლებელია შემდეგნაირად:
კონსტანტა უკვე იცით
ალბათ რაც არის, ვინც არ იცით კონსტანტა არის ცვლადი რომლის დეფინირებაც ხდება public static final საკვანძო სიტყვების
კომბინირებით, public რა თქმა უნდ ამ კონკრეტულ შემთხვევაში არჩევითი მოდიფიკატორია, მაგრამ
ჯავას კომპილატორი ენუმერაციას სწორედ ამ მოდიფიკატორს ანიჭებს, მომდევნო საკვანძო
სიტყვებთან ერთად კადრს მიღმა. კომპილატორი ასევე მემკვიდრეობასაც ქმნის ენუმერაციის შექმნის დროს, კომპილირების შემდგომ
თუ გახედავთ ბაითკოდს, ნახავთ რო თქვენს მიერ დეკლარირებული ენუმერაცია მემკვიდრეა
Enum კლასის
და ის არის მონიშნული,
როგორც ფინალური, რადგან მისგან ობიეკტი არ იქმნება, გამომდინარე იქიდან რო უკვე მემკვიდრეა
კლასის, შეუძლებელია სხვა მემკვიდრეობის ქონა, გახსოვთ ალბათ რო
ჯავა მხოლოდ ერთ პირდაპირ მემკვიდრეოაბას ცნობს, თუმცა შესაძლებელია უამრავი ინტერფეისების
იმპლემენტირება (რაც თავის მხრივ მემკვიდრეობაა)
ვინაიდან და რადგანაც
კონსტანტების ერთობა გვაქ, ხშირად მოგიწევთ ენუმერაციის გამოყენება if, else statement-ში და switch statement-ში. მათი შედარება ხდება პირდაპირ == ოპერატორის მეშვეობით, თუმცა თქენ ეგ არ გზღუდავთ იმისგან რო საკუთარი შედარების მეთოდი (equals) დაწეროთ და მოახდინოთ
მისი გამოყენება თქვენი გემოვნების მიხედვით. სხვაობა == ოპერატორს და equals() მეთოდს შორის კომპილირების
დროს ტიპის შემოწმებაა, მაგალითად თუ შევადარებთ == ოპერატორით ორ ენუემრაციას, რომელიმე
რომ NULL აღმოჩნდეს პროგრამის მუშაობის დროს (At Run Time) არ მოხდება NullPointerException-ის სროლა, იგივე
გარანტიას equals() მეთოდი არ მოგცემთ. თუმცა მე პირადად
მირჩევნია equals() მეთოდის გამოყენება რადგან ვნახო სად შეიცავს კოდი გამონაკლისის საფრთხეს.
მოკლედ გემოვნების და კოდის წერის სტილით განისაზღვრება მათი გამოყენება.
ენუმერაცია რომელსაც
ყველაზე ხშირად გამოიყენებთ, დააყენეთ პირველ ადგილზე ოპერაციების გამოყენების დროს,
უკეთესი შედეგისთვის. რატომ უნდა დავაყენოთ პირველზე, ამაზე ძველ ბლოგებში ვილაპარაკეთ.
მაღლა ხსენებული სიკეთეების
გარდა კომპილატორი ახდენს 4 მეთოდის დეფინირებასაც, რომლებიც გვეხმარებიან იტერაციაში,
სახელის მოძიებაში, ღირებულების მოძიებაში და ინდექსების მოძიებაში. ესენია, values(), ordinal(),
name(), valueOf(). არის აგრეთვე compareTo მეთოდი Comparable ინტერფეისიდან. ვნახოთ
ეს მეთოდები.
Values() არის იტერატორი, რომელიც
არის ჩვეულებრივი მასივი ენუმ ღირებულებების.
Oridnal() გვაჩვენებს ინდექსებს.
Name() გვაჩვენებს კონსტანტების
სახელებს.
valueOf() იღებს კონსტანტის
სახელს და გვიბრუნებს ენუმერაციას.
კომპილირების შემდგომ:
valueOf() აბრუნებს ობიეკტს,
მაგრამ კომპილატორმა მაინც ანახა შედეგი როგორც
ხედავთ, იმიტომ რომ კომპილატორი Enum კლასში, რომლის მემკვიდრეც არის ჩვენი enum ახდენს toString() მეთოდის გადაწერასაც.
შეგიძლიათ ეგ მეთოდით, თქვენი გემოვნების მიხედვით გადაწეროთ და სტაკში ის იმფორმაცია
იქონიოთ, რომელის ნახვაც გსურთ.
compareTo- მეთოდით შეგიძლიათ
ენუმერაცია დააწყოთ იმ დანმიმდევრობით რა თანმიმდევრობითაც გსურთ. სტანდარტულად ის
მექსიერებაში განლაგებულია ნატურალური თანმიმდევრობით.
სულ
ეს არის ენუმერაცია. მარტივია ძალიან, მაგრამ რა გამოარჩევს ჯავა ენუმერაციას სხვებისგან.
მაღლა დავწერე რომ ესენია, ცვლადები, მეთოდები, კონსტრუკტორი, პარამეტრების მიღების
უნარი, გადაწერა, მისი გამოყენება შესაძლებელია როგორც სინგელტონ კლასის (ამაზე ახლა
არ ვისაუბრებ), შესაძლებელია მისგან JSON ობიეკტის შექმნა
(არც ამასე ვისაუბრებთ), მაგრამ რაზეც არ დამიწერია რო არ ვისაუბრებთქო ეგენი განვიხილოთ,
მაგალითებთან ერთად. მაშ ასე:
1. ენუმერაციას აქვს უნარი
მიიღოს პარამეტრები.
პარამეტრი () -ში მოქცეული ინფორმაცია,
სურათზე ერთი პარამეტრი გვაქ, თუმცა თქვენ შეგიძლიათ მიანიჭოთ იმდენი
ღირებულება რამდენის აუცილებლობაც გაგაჩნიათ. მთავარი რამ რაც ღირებულების
მინიჭების დროს უნდა გახსოვდეთ არის ის რომ, ენუმის შექმნის დროს ყველა
ღირებულების დეფინირება უნდა მოხდეს კონსტრუკტორში. მაგალითისთვის:
ალბათ ხვდებით რატომაც ხდება ღირებულების
გადაცემა კონსტრუკტორზე, თუ ვერ მიხვდით დააკვირდით ფოტოს.
ასე გამოიყურება ჩვენი ენუმერაცია
კომპილირების შემდგომ, როგორც ხედავთ რეალურად როცა ჩვენ კონსტანტის დეფინირებას
ვახდენთ, კომპილატორი ქმნის ობიეკტს კლასის სახელწოდებით რომელიც არის კონსტანტური
ღირებულების, შემდგომ სტატიკურ მეთოდში კი ახდენს მათ ინიციალიზირებას, სტატიკური
ბლოკის ეგზეკუცია რომ მთავარ მეთოდამდე ხდება ეგეც გემახსოვრებათ. აუცილებელია
კონსტრუკტორს გადავაწოდოთ ტიპები იმ თანმიმდევრობით, რა თანმიმდევრობითაც გვინდა
მათი გამოყენება კონსტანტურ ველებში, რატომ და რისთვის ხდება ასე მეთოდებ-ზე
საუბროს დროს განვიხილეთ, თუ ვერ ხვდებით შეგიძლიათ ჯერ ჯავას მეთოდებს გაეცნოთ.
2. ენუმერაციას შეუძლია ექნეს
კონსტრუკტორი. Default ან Private მოდიფიკატორით. მაგალითი მაღლა ვნახეთ.
3. ენუმერაცია შეუძლია ექნეს
ცვლადები.
4. ენუმერაციას შესაძლებელია
ექნეს მეთოდები, მათ შორის Main
მეთოდიც.
სურათზე ხედავთ აბსტრაკტულ მეთოდსაც, როგორც
ვიცით აბსტრაკტული მეთოდის მიზანია რომ ის გადაეცეს მემკვიდრე კლას და მოხდეს მისი
გადაწერა, ენუმერაციას მემკვიდრე კლასი ვერ ეყოლება იმიტო რო ფინალურია, მაშინ სად
მიდის აბსტრაკტული მეთოდი? აბსტრაკტული მეთოდი მიდის საკუთარ თავთან, ენუმერაციაში
თუ ვახდენთ აბსტრაკტული მეთოდის დეფინირებას მისი გადაწერა აუცილებლად უნდა მოხდეს
კონსტანტის გასწვრივ, ანონიმურ კლასში, პროგრამისტები ამ ფრჩხილებს კონსტანტურად სპეციფიურ კლასაც ეძახიან, ზოგი რეფერენტულ ფრჩხილებსაც ეძახის, მაგრამ არ აქვს მნისნელობა, შეგიძლიათ ზებრა დაუძახოთ, მთავარია გახსოვდეთ რას აკეთებს.
კონსტანტის გასწვრივ შეგიძლიათ გადაწეროთ
ნებისმიერი სხვა მეთოდიც, რომელიც არ არის აბსტრაკტული.
ენუმერაციის შენახვა
ლოკალურად შესაძლებელია სტრუკტურებში, ჯავაში არსებობს სპეციალური სტრუკტურები, რომლებიც
ამაში დაგეხმარებიან, ესენია EnumSet და EnumMap.
მათზე არ ვისაუბრებთ,
რადგან თუ რომელიმე სტრუკტურის გამოყენება იცით, მათ გამოყენებასაც შეძლებთ ურპბოლემოდ.
თუ არ იცით, გახედეთ ჩემ ბლოგს სტრუკტურებზე.
და მაინც, სად გამოვიყენოთ
ენუმერაცია, ყველაზე ხშირად ეს კითხვა დაიბადება ალბათ. რეალურ ცხოვრებაში რა გარემოში
ვიყენებთ მას? წარმოიდგინეთ მუშაობთ, რომელიმე Delivery ფირმაში, რომელიც
ახდენს ნებისმიერი პროდუკტის მიტანას კლიენტამდე, მართებული იქნება ასეთ დროს შევქმნათ
ენუმერაცია რომელიც გვეტყვის შემდეგ ინფორმაციას, პროდუკტი მომზადების პროცესშია, პროდუკტი
მზად არის, პროდუკტი ადგილზეა, პროდუკტის მიტანა ვერ მოხერხდა ადგილზე. მოვახდენთ ენუმერაციის შექმნას, 3 კონსტანტით, ORDERED, READY,
DELIVERED. მეტი მოქნილობისთვის შევქმნით 3 მეთოდს რომელიც ამ 3 კონსტანტას აღწერს,
Boolean
isOrdered, Boolean isReady, Boolean isDelivered, რომელთაც გადავწერთ კონსტანტების გასწვრივ.
რომელიმე კონსტანტის
გამოძახება თუ მოხდა, ზუსტად გვეცოდინება რო ოპერაცია შესრულდა. დამატებითი დამაჯერებლობისთვის, რომელიმე კლასში საიდანაც ვახდენთ რაიმე სახის ოპერაციების წარმოებას, მოვახდენთ ენუმსეტის დეფინრიებას
სადაც მოავხდენთ პროდუკტის
მომზადების და მიტანის შენახვას შესაბამისად პროდუკტი რომელიც არ მოხვდება ამ სეტში
არ არის მომხმარებლამდე მისული, ამის შემდგომ ერთი მარტივი მეთოდით
გვექნება სია ყველა
პროდუკტის, რომელმაც ვერ მიაღწია კლიენტამდე. ეს უბრალო ენუმერაცია გვაძლევს საშუალეაბს
უზარმაზარი პროეკტი შევქმნათ, სადაც გვექნება მომხმარებელთან მიტანის დრო, პროდუკტების
სახეობა, პროდუკტების ვალიდირება და ყველაფერი სხვა რამ რაც შეიძლება პრუდუკტს უკავშირდებოდეს.
შესაბამისად თავიდან ავირიდებთ უამრავი if..else, switch გამოხატულებების წერას
რაც კოდს უფრო წაკითხვადს, მოქნილს და კომპაკტურს გახდის, ყველაფერთან ერთად, ბონუსად
შეგვიძლია ამ ინფორმაციის JSON ობიეკტად გადაკეთება, რაც ძალიან გამოსადეგი რამ
არის რეალურ პროგრამირებაში, მაღლა ვთქვი რო ამაზე არ ვისაუბრეთ, ისე როგორც Singleton კლასებზე. ამიტო აქ
მოვრჩებით ენუმერაციაზე საუბარს, იმედია იდეა გასაგებია, შეუძლებელია გასაგები არ იყოს,
იმდენად მარტივია. რეალურ პროგრამირებაში როგორ ხდება მისი გამოყენება ამის მცირედი
მაგალითიც ნახეთ, დანარჩენი თქვენ ფანტაზიაზეა დამოკიდებული. წარმატებები.