ওহে! আজ আমরা জাভার বিশেষ ডেটা টাইপগুলির মধ্যে একটি সম্পর্কে কথা বলব:
Enum
("গণনা" এর জন্য সংক্ষিপ্ত)। কি এটা বিশেষ করে তোলে? একটি প্রোগ্রামে "মাস" বাস্তবায়নের জন্য আমাদের কী দরকার তা কল্পনা করা যাক। সমস্যাযুক্ত বলে মনে হচ্ছে না, তাই না? আমরা শুধু নির্ধারণ করতে হবে কি বৈশিষ্ট্য যে কোন মাসে আছে. সম্ভবত আমাদের প্রথমে মাসের নাম এবং এতে দিনের সংখ্যা প্রয়োজন। সমাধানটি বেশ সহজ দেখায়:
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 +
'}';
}
}
পুরো শবাং! আমাদের একটি Month
ক্লাস আছে, প্রয়োজনীয় ক্ষেত্র, গেটার/সেটার এবং toString()
। যদি না, অবশ্যই, আমাদের যোগ করতে হবে equals()
এবংhashCode()
সম্পূর্ণ সুখ অর্জন :) কিন্তু এখানে আমাদের একটি ধারণাগত সমস্যা আছে। আপনি সম্ভবত মনে রাখবেন, OOP এর একটি প্রধান সুবিধা হল যে এটি বাস্তব বিশ্বের থেকে সত্ত্বাকে মডেল করা সহজ করে তোলে। একটি চেয়ার, একটি গাড়ি, একটি গ্রহ - সাধারণ জীবন থেকে এই সমস্ত ধারণাগুলি সহজেই বিমূর্ততার সাহায্যে একটি প্রোগ্রামে উপস্থাপন করা হয়। সমস্যা হল কিছু বাস্তব-বিশ্বের সত্তার মানগুলির কঠোরভাবে সীমিত পরিসর রয়েছে। বছরে মাত্র ৪টি ঋতু থাকে। একটি অষ্টকটিতে মাত্র 8টি নোট রয়েছে। ক্যালেন্ডারে মাত্র 12 মাস আছে। এবং Ocean's 11 এর Danny Ocean-এর মাত্র 11 জন বন্ধু আছে (যদিও এটা কোন ব্যাপার না :)) ব্যাপারটা হল যে একটি সাধারণ জাভা শ্রেণী এই সত্তাগুলিকে মডেল করতে এবং তাদের প্রাকৃতিক সীমাবদ্ধতাগুলি প্রয়োগ করতে সক্ষম নয়৷ আমাদেরMonth
ক্লাসে সমস্ত প্রয়োজনীয় ক্ষেত্র রয়েছে। কিন্তু যদি অন্য প্রোগ্রামার এটি ব্যবহার করে, কেউ তাকে সম্পূর্ণরূপে উন্মাদ বস্তু তৈরি করা থেকে আটকাতে পারবে না:
public class Main {
Month month1 = new Month("lolkek", 322);
Month month2 = new Month("yahoooooooooooo", 12345);
}
যদি এটি আমাদের কোডে উপস্থিত হয়, তাহলে অপরাধীকে খুঁজে পাওয়া সহজ হবে না! একদিকে, অবজেক্ট তৈরি করা প্রোগ্রামার বুঝতে পারে যে Month
ক্লাস মানে "এক বছরে মাস" এবং এই ধরনের বাজে কথা লিখবে না। অন্যদিকে, প্রোগ্রামার শুধুমাত্র ক্লাস ডিজাইনার প্রদত্ত ক্ষমতার সুবিধা নিচ্ছে। নির্বিচারে নাম এবং দিনের সংখ্যা নির্ধারণ করা কি সম্ভব? যে আমরা পেয়েছিলাম ঠিক কি. তাহলে এই পরিস্থিতিতে আমাদের কী করা উচিত? সত্যি বলতে, জাভা 1.5 প্রকাশের আগে, প্রোগ্রামারদের সৃজনশীল হতে হয়েছিল :) সেই দিনগুলিতে, তারা এই ধরনের কাঠামো তৈরি করেছিল:
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 +
'}';
}
}
উদাহরণটি সংক্ষিপ্ত করার জন্য এখানে আমরা মাসের সংখ্যা বারো থেকে তিনে কেটেছি। এই ধরনের নকশা সমস্যা সমাধান করা সম্ভব. বস্তু তৈরি করার ক্ষমতা একটি ব্যক্তিগত কনস্ট্রাক্টরের মধ্যে সীমাবদ্ধ ছিল:
private Month(String name, int daysCount) {
this.name = name;
this.daysCount = daysCount;
}
ক্লাস ব্যবহার করে প্রোগ্রামাররা কেবল Month
বস্তু তৈরি করতে পারে না। তাদের ক্লাস ডেভেলপার দ্বারা প্রদত্ত চূড়ান্ত স্ট্যাটিক অবজেক্ট ব্যবহার করতে হয়েছিল। উদাহরণস্বরূপ, এই মত:
public class Main {
public static void main(String[] args) {
Month january = Month.JANUARY;
System.out.println(january);
}
}
কিন্তু, জাভা ডেভেলপাররা বিদ্যমান সমস্যার দিকে দৃষ্টি আকর্ষণ করেছে। অবশ্যই, এটি দুর্দান্ত যে প্রোগ্রামাররা ভাষায় উপলব্ধ সরঞ্জামগুলি ব্যবহার করে একটি সমাধান নিয়ে আসতে সক্ষম হয়েছিল, তবে এটি খুব সহজ বলে মনে হচ্ছে না! একটি সুস্পষ্ট সমাধান প্রয়োজন ছিল, এমনকি novices জন্য. এবং তাই Enum
জাভা হাজির. মূলত, Enum
একটি জাভা ক্লাস যা বস্তুর মানগুলির একটি সীমিত সেট সরবরাহ করে। এটি দেখতে কেমন তা এখানে:
public enum Month {
JANUARY,
FEBRUARY,
MARCH
}
সংজ্ঞায়, আমরা ইঙ্গিত দিয়েছি যে Enum
এটি একটি জাভা ক্লাস, কিন্তু এটি কি সত্যিই সত্য? হ্যাঁ, এবং আমরা এটি যাচাই করতেও পারি। উদাহরণস্বরূপ, আমাদের Month
এনামকে অন্য কোনো শ্রেণির উত্তরাধিকারী করার চেষ্টা করুন:
public abstract class AbstractMonth {
}
// Error! The extends clause cannot be used with an enum
public enum Month extends AbstractMonth {
JANUARY,
FEBRUARY,
MARCH
}
কেন যে ঘটবে? যখন আমরা লিখি:
public enum Month
কম্পাইলার এই বিবৃতিটিকে নিম্নলিখিত কোডে রূপান্তর করে:
public Class Month extends Enum
আপনি ইতিমধ্যে জানেন, জাভা একাধিক উত্তরাধিকার সমর্থন করে না। অতএব, আমরা উত্তরাধিকারী হতে পারি না AbstractMonth
। কিভাবে এই নতুন নির্মাণ Enum
ব্যবহার করা যেতে পারে? এবং কিভাবে এটি ক্ষেত্র সহ পুরানো নির্মাণ থেকে পৃথক static final
? ভাল, একটি উদাহরণ হিসাবে, পুরানো নির্মাণ আমাদের বিবৃতিতে আমাদের নিজস্ব মান ব্যবহার করতে দেয়নি switch
। কল্পনা করুন যে আমরা এমন একটি প্রোগ্রাম তৈরি করতে চাই যা আমাদের প্রতি মাসে উদযাপন করা ছুটির কথা মনে করিয়ে দেবে:
public class HolidayReminder {
public void printHolidays(Month month) {
switch (month) {
// Error!
case JANUARY:
}
}
}
আপনি দেখতে পাচ্ছেন, কম্পাইলার এখানে একটি ত্রুটি নিক্ষেপ করে। কিন্তু একবার enum
জাভা 1.5 এ উপস্থিত হলে, সবকিছু অনেক সহজ হয়ে গেছে:
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);
}
}
কনসোল আউটপুট:
New Year's Day is January 1st!
নোট করুন যে Enum
অবজেক্টগুলিতে অ্যাক্সেস স্থির ছিল, ঠিক যেমনটি জাভা 1.5 এর আগে ছিল। Month
মাসগুলি অ্যাক্সেস করার জন্য আমাদের কোনও বস্তু তৈরি করার দরকার নেই । Enum
enums এর সাথে কাজ করার সময়, এটি একটি পূর্ণাঙ্গ শ্রেণী ভুলে যাওয়া খুব গুরুত্বপূর্ণ । এর মানে হল, যদি প্রয়োজন হয়, আপনি এতে কনস্ট্রাক্টর এবং পদ্ধতিগুলি সংজ্ঞায়িত করতে পারেন। উদাহরণস্বরূপ, পূর্ববর্তী কোড খণ্ডে, আমরা কেবলমাত্র মানগুলি নির্দিষ্ট করেছি: JANUARY, FEBRUARY, MARCH৷ যাইহোক, আমরা আমাদের Month
enum এভাবে প্রসারিত করতে পারি:
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 +
'}';
}
}
এখানে আমরা আমাদের enum
2টি ক্ষেত্র (মাসের নাম এবং দিনের সংখ্যা), একটি কনস্ট্রাক্টর দিয়েছি যা এই ক্ষেত্রগুলি, গেটার/সেটার, পদ্ধতি toString()
এবং 2টি স্ট্যাটিক পদ্ধতি ব্যবহার করে। আপনি দেখতে পাচ্ছেন, এতে কোন সমস্যা ছিল না। আবার, Enum
সত্যিই একটি পূর্ণাঙ্গ শ্রেণী:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
System.out.println(Arrays.toString(Month.getSummerMonths()));
}
}
কনসোল আউটপুট:
[Month{name='June', daysCount=30}, Month{name='July', daysCount=31}, Month{name='August', daysCount=31}]
অবশেষে, আমি একটি অত্যন্ত দরকারী জাভা বই সুপারিশ করতে চাই, যথা Joshua Bloch দ্বারা "কার্যকর জাভা" । লেখক জাভা-এর একজন নির্মাতা, তাই আপনি কীভাবে সঠিকভাবে এবং দক্ষতার সাথে ভাষার সরঞ্জামগুলি ব্যবহার করবেন সে সম্পর্কে তার পরামর্শে অবশ্যই বিশ্বাস করতে পারেন :) আমাদের পাঠের বিষয়ে, আমি আপনাকে বইয়ের অধ্যায়ে বিশেষ মনোযোগ দেওয়ার পরামর্শ দিচ্ছি Enum
। শুভ পড়ার! :)
GO TO FULL VERSION