CodeGym /Java Blog /এলোমেলো /জাভাতে মডিফায়ার অ্যাক্সেস করুন
John Squirrels
লেভেল 41
San Francisco

জাভাতে মডিফায়ার অ্যাক্সেস করুন

এলোমেলো দলে প্রকাশিত
ওহে! আজকের পাঠে, আমরা অ্যাক্সেস মডিফায়ারের ধারণার সাথে পরিচিত হব এবং তাদের সাথে কীভাবে কাজ করতে হবে তার উদাহরণ বিবেচনা করব। অবশ্যই, 'পরিচিত হও' বলাটা মোটেও ঠিক নয়: আপনি পূর্ববর্তী পাঠ থেকে তাদের বেশিরভাগের সাথে ইতিমধ্যেই পরিচিত। শুধু ক্ষেত্রে, এর সবচেয়ে গুরুত্বপূর্ণ পয়েন্ট আমাদের স্মৃতি রিফ্রেশ করা যাক. মডিফায়ার অ্যাক্সেস প্রায়শই কীওয়ার্ড যা আপনার কোডের বিভিন্ন অংশে অ্যাক্সেস নিয়ন্ত্রণ করে। কেন 'বেশিরভাগ সময়'? কারণ তাদের মধ্যে একটি কীওয়ার্ড ব্যবহার না করেই ডিফল্টভাবে সেট করা থাকে :) জাভাতে চারটি অ্যাক্সেস মডিফায়ার রয়েছে। আমরা সেগুলিকে সর্বাধিক সীমাবদ্ধ থেকে সবচেয়ে 'নরম' পর্যন্ত তালিকাভুক্ত করি:
  • ব্যক্তিগত;
  • ডিফল্ট (প্যাকেজ দৃশ্যমান);
  • সুরক্ষিত
  • পাবলিক
আসুন তাদের প্রতিটির দিকে একবার নজর দিই এবং সেগুলি কখন কার্যকর হতে পারে তা চিহ্নিত করি৷ এবং আমরা উদাহরণ দেব :)

ব্যক্তিগত সংশোধক

অ্যাক্সেস মডিফায়ার।  ব্যক্তিগত, সুরক্ষিত, ডিফল্ট, সর্বজনীন - 2ব্যক্তিগত হল সবচেয়ে সীমাবদ্ধ অ্যাক্সেস সংশোধক। এটি একটি একক শ্রেণীর মধ্যে ডেটা এবং পদ্ধতির দৃশ্যমানতা সীমাবদ্ধ করে। আপনি গেটার এবং সেটার সম্পর্কে পাঠ থেকে এই সংশোধকটি জানেন। এই উদাহরণ মনে আছে?

public class Cat {

   public String name;
   public int age;
   public int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }
}

public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       cat.name = "";
       cat.age = -1000;
       cat.weight = 0;
   }
}
আমরা এটি পূর্ববর্তী পাঠে বিবেচনা করেছি। আমরা এখানে একটি গুরুতর ভুল করেছি: আমরা আমাদের ডেটা সর্বজনীন করি, যা সহ প্রোগ্রামারদের সরাসরি ক্ষেত্রগুলি অ্যাক্সেস করতে এবং তাদের মান পরিবর্তন করতে দেয়। আর কি... এই মানগুলো কোনো চেক ছাড়াই বরাদ্দ করা হয়েছে। এর মানে হল যে আমাদের প্রোগ্রামটি "" নামের একটি বিড়াল তৈরি করতে পারে যার বয়স -1000 বছর এবং ওজন 0। এই সমস্যাটি সমাধান করার জন্য, আমরা গেটার এবং সেটার্স ব্যবহার করেছি এবং ডেটাতে অ্যাক্সেস সীমিত করতে ব্যক্তিগত সংশোধকও ব্যবহার করেছি।

public class Cat {

   private String name;
   private int age;
   private int weight;

   public Cat(String name, int age, int weight) {
       this.name = name;
       this.age = age;
       this.weight = weight;
   }

   public Cat() {
   }

   public void sayMeow() {
       System.out.println("Meow!");
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       // input parameter check
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       // input parameter check
       this.age = age;
   }

   public int getWeight() {
       return weight;
   }

   public void setWeight(int weight) {
       // input parameter check
       this.weight = weight;
   }
}
মূলত, ক্ষেত্রগুলিতে অ্যাক্সেস সীমিত করা এবং গেটার এবং সেটার্স প্রয়োগ করা কতটা ব্যক্তিগত তার সবচেয়ে সাধারণ উদাহরণবাস্তব কাজে ব্যবহার করা হবে। অন্য কথায়, এই মডিফায়ারের মূল উদ্দেশ্য হল একটি প্রোগ্রামে এনক্যাপসুলেশন অর্জন করা। এটি শুধুমাত্র ক্ষেত্রগুলিতে প্রযোজ্য নয়, উপায় দ্বারা। কল্পনা করুন যে আপনার প্রোগ্রামে একটি পদ্ধতি রয়েছে যা কিছু খুব জটিল কার্যকারিতা প্রয়োগ করে। আমরা একটি উদাহরণ হিসাবে কি সুপারিশ করতে পারেন? ধরা যাক আপনার readDataFromCollider() পদ্ধতিটি একটি ডেটা ঠিকানা ইনপুট হিসাবে গ্রহণ করে, বাইট বিন্যাসে লার্জ হ্যাড্রন কোলাইডার থেকে ডেটা পড়ে, এই ডেটাটিকে পাঠ্যে রূপান্তর করে, এটি একটি ফাইলে লিখে এবং প্রিন্ট করে। এমনকি পদ্ধতির একটি বর্ণনাও ভয়ঙ্কর দেখাচ্ছে, কোডের কিছুই বলার নেই :) কোডটিকে আরও পাঠযোগ্য করার জন্য, পদ্ধতির সমস্ত জটিল যুক্তি এক জায়গায় না লেখাই ভাল হবে। পরিবর্তে, আমাদের কার্যকারিতাকে পৃথক পদ্ধতিতে বিচ্ছিন্ন করা উচিত। উদাহরণস্বরূপ, readByteData()মেথড ডাটা পড়ার জন্য দায়ী, convertBytesToSymbols() মেথড কলাইডার থেকে পড়া ডাটাকে টেক্সটে রূপান্তর করে, saveToFile() মেথড প্রাপ্ত টেক্সটকে ফাইলে সেভ করে এবং printColliderData() মেথড আমাদের ডাটা ফাইল প্রিন্ট করে। শেষ পর্যন্ত, আমাদের readDataFromCollider() পদ্ধতিটি আরও সহজ হবে:

public class ColliderUtil {

   public void readDataFromCollider(Path pathToData) {
       byte[] colliderData = readByteData(pathToData);
       String[] textData = convertBytesToSymbols(colliderData);
       File fileWithData = saveToFile(textData);
       printColliderData(fileWithData);
   }

   public byte[] readByteData(Path pathToData) {

       // Reads data in bytes
   }

   public String[] convertBytesToSymbols(byte[] colliderDataInBytes) {

       // Converts bytes to characters
   }

   public File saveToFile(String[] colliderData) {

       // Saves read data to a file
   }

   public void printColliderData(File fileWithColliderData) {

       // Prints data from the file
   }
}
যাইহোক, আপনি ইন্টারফেস সম্পর্কে পাঠ থেকে মনে রাখবেন, ব্যবহারকারী শুধুমাত্র বাহ্যিক ইন্টারফেসে অ্যাক্সেস পায়। এবং আমাদের 4টি পদ্ধতি এটির অংশ নয়। এগুলি সহায়ক পদ্ধতি: আমরা কোডের পাঠযোগ্যতা উন্নত করতে এবং একটি পদ্ধতিতে চারটি ভিন্ন কাজকে ক্র্যাম না করার জন্য এগুলি তৈরি করেছি৷ আপনাকে এই পদ্ধতিগুলিতে ব্যবহারকারীকে অ্যাক্সেস দেওয়ার দরকার নেই। কলাইডারের সাথে কাজ করার সময় ব্যবহারকারীদের যদি convertBytesToSymbols() পদ্ধতিতে অ্যাক্সেস থাকে, তাহলে তারা সম্ভবত পদ্ধতিটি দেখে বিভ্রান্ত হবেন এবং ভাববেন এটি কিসের জন্য। কি বাইট রূপান্তরিত হয়? তারা কোথাথেকে এসেছে? কেন তাদের পাঠ্য রূপান্তর? এই পদ্ধতিতে সম্পাদিত যুক্তি ব্যবহারকারীর কাছে উন্মুক্ত ইন্টারফেসের অংশ নয়। শুধুমাত্র readDataFromCollider()পদ্ধতি ইন্টারফেসের অংশ। তাহলে এই চারটি 'অভ্যন্তরীণ' পদ্ধতি দিয়ে আমরা কী করব? ঠিক! তাদের অ্যাক্সেস সীমিত করতে ব্যক্তিগত সংশোধক ব্যবহার করুন । এটি করার ফলে তারা ব্যবহারকারীকে বিভ্রান্ত না করে ক্লাসের ভিতরে শান্তিপূর্ণভাবে তাদের কাজ সম্পাদন করতে দেয়, যার প্রতিটি পৃথক পদ্ধতির যুক্তি জানার প্রয়োজন নেই।

public class ColliderUtil {

   public void readDataFromCollider(Path pathToData) {
       byte[] colliderData = readByteData(pathToData);
       String[] textData = convertBytesToSymbols(colliderData);
       File fileWithData = saveToFile(textData);
       printColliderData(fileWithData);
   }

   private byte[] readByteData(Path pathToData) {
       // Reads data in bytes
   }

   private String[] convertBytesToSymbols(byte[] colliderDataInBytes) {
       // Converts bytes to characters
   }

   private File saveToFile(String[] colliderData) {
       // Saves read data to a file
   }

   private void printColliderData(File fileWithColliderData) {
       // Prints data from the file
   }
}

সুরক্ষিত সংশোধক

পরবর্তী সবচেয়ে সীমাবদ্ধ সংশোধক সুরক্ষিতসুরক্ষিতঅ্যাক্সেস মডিফায়ার।  ব্যক্তিগত, সুরক্ষিত, ডিফল্ট, সর্বজনীন - 3 অ্যাক্সেস মডিফায়ার দ্বারা চিহ্নিত ক্ষেত্র এবং পদ্ধতিগুলি দৃশ্যমান হবে:
  • আমাদের মতো একই প্যাকেজে অন্তর্ভুক্ত সকল শ্রেণীর মধ্যে;
  • আমাদের ক্লাসের উত্তরাধিকারী সমস্ত শ্রেণীর মধ্যে।
প্রথমে, কখন এটির প্রয়োজন হতে পারে তা কল্পনা করা কঠিন। আশ্চর্য হবেন না: প্রাইভেট-এর তুলনায় সুরক্ষিত- এর জন্য ব্যবহার করার ক্ষেত্রে অনেক কম আছে , এবং সেগুলি খুব নির্দিষ্ট। কল্পনা করুন যে আমাদের কাছে একটি AbstractSecretAgent বিমূর্ত শ্রেণী রয়েছে যা কিছু গোয়েন্দা পরিষেবাতে একটি গোপন এজেন্টকে প্রতিনিধিত্ব করে, সেইসাথে একটি top_secret প্যাকেজ যা এই শ্রেণী এবং এর বংশধরদের ধারণ করে। কংক্রিট ক্লাস যেমন FBISecretAgent , MI6SecretAgent , MossadSecretAgent , ইত্যাদি এটি উত্তরাধিকার সূত্রে প্রাপ্ত। বিমূর্ত শ্রেণীর ভিতরে, আমরা একটি এজেন্ট কাউন্টার বাস্তবায়ন করতে চাই। প্রোগ্রামের কোথাও একটি নতুন এজেন্ট তৈরি করা হলে এটি বৃদ্ধি পাবে। প্যাকেজ top_secret;

public abstract class AbstractSecretAgent {

   public static int agentCount = 0;
}
কিন্তু আমাদের এজেন্টরা গোপন! এর মানে হল যে তারা এবং অন্য কারো জানা উচিত নয় যে তাদের মধ্যে কতজন আছে। আমরা সহজেই agent_counter ক্ষেত্রে সুরক্ষিত সংশোধক যোগ করতে পারি । তাহলে আমাদের টপ_সিক্রেট প্যাকেজে থাকা অন্যান্য সিক্রেট এজেন্ট ক্লাস এবং অন্যান্য ক্লাসের উদাহরণ এর মান পেতে পারে।

public abstract class AbstractSecretAgent {

   protected static int agent_counter = 0;
}
এবং এটি এমন একটি বিশেষ কাজ যার জন্য সুরক্ষিত সংশোধক প্রয়োজন :)

প্যাকেজ দৃশ্যমান পরিবর্তনকারী

তালিকার পরবর্তী ডিফল্ট সংশোধক, যা প্যাকেজ দৃশ্যমান সংশোধক হিসাবেও পরিচিত । এটি একটি কীওয়ার্ড দ্বারা নির্দেশিত নয়, যেহেতু Java ডিফল্টরূপে সমস্ত ক্ষেত্র এবং পদ্ধতিতে এটি প্রয়োগ করে। আপনি যদি আপনার কোডে নিম্নলিখিত লিখুন:

int x = 10
x ভেরিয়েবলের এই প্যাকেজটি দৃশ্যমান অ্যাক্সেস থাকবে এটা কি করে তা মনে রাখা সহজ। মূলত, ডিফল্ট = সুরক্ষিত উত্তরাধিকার :) সুরক্ষিত মডিফায়ারের মতো, এর প্রয়োগ সীমিত। প্রায়শই, ডিফল্ট অ্যাক্সেস এমন একটি প্যাকেজে ব্যবহার করা হয় যেখানে কিছু ইউটিলিটি ক্লাস রয়েছে যা প্যাকেজের অন্যান্য সমস্ত ক্লাসের কার্যকারিতা বাস্তবায়ন করে না। একটা উদাহরণ দেওয়া যাক। কল্পনা করুন যে আমাদের একটি 'পরিষেবা' প্যাকেজ আছে। এটিতে বিভিন্ন ক্লাস রয়েছে যা একটি ডাটাবেসের সাথে কাজ করে। উদাহরণস্বরূপ, একটি UserService ক্লাস আছে যা ডাটাবেস থেকে ব্যবহারকারীর ডেটা পড়ে, একটি CarServiceক্লাস যা একই ডাটাবেস থেকে গাড়ির ডেটা পড়ে এবং অন্যান্য ক্লাস, যার প্রতিটি নির্দিষ্ট ধরণের অবজেক্টের সাথে কাজ করে এবং ডেটাবেস থেকে সংশ্লিষ্ট ডেটা পড়ে।

package services;

public class UserService {
}

package services;

public class CarService {
}
কিন্তু ডাটাবেসের ডেটা এক ফরম্যাটে থাকা সহজ হবে এবং আমাদের এটি অন্য ফর্ম্যাটে প্রয়োজন। কল্পনা করুন যে ডাটাবেসে ব্যবহারকারীদের জন্মতারিখ <টাইমস্ট্যাম্প উইথ টাইম জোন> হিসাবে সংরক্ষণ করা হয়েছে...

2014-04-04 20:32:59.390583+02
...এবং পরিবর্তে আমাদের সবচেয়ে সহজ বস্তুর প্রয়োজন - একটি java.util.Date । এই সমস্যা সমাধানের জন্য, পরিষেবা প্যাকেজের ভিতরে, আমরা একটি বিশেষ ম্যাপার ক্লাস তৈরি করতে পারি। এটি ডাটাবেস থেকে আমাদের পরিচিত জাভা অবজেক্টে ডেটা রূপান্তরের জন্য দায়ী। একটি সাধারণ সাহায্যকারী শ্রেণী। আমরা সাধারণত সব ক্লাসকে পাবলিক ক্লাস ClassName হিসাবে ঘোষণা করি , কিন্তু এটি একটি প্রয়োজনীয়তা নয়। আমরা আমাদের হেল্পার ক্লাসকে ক্লাস ম্যাপার হিসাবে ঘোষণা করতে পারি । এই ক্ষেত্রে, এটি এখনও তার কাজ করে, কিন্তু পরিষেবা প্যাকেজের বাইরের কারও কাছে এটি দৃশ্যমান নয় !

package services;

class Mapper {
}


package services;

public class CarService {

   Mapper mapper;
}
এবং এখানে মৌলিক যুক্তি: প্যাকেজের বাইরের কাউকে কেন একটি সহায়ক ক্লাস দেখতে হবে যা শুধুমাত্র সেই প্যাকেজের ক্লাসগুলির সাথে কাজ করে?

পাবলিক সংশোধক

এবং শেষ কিন্তু অন্তত না, পাবলিক সংশোধক! আপনি CodeGym-এ আপনার অধ্যয়নের প্রথম দিনে এই মডিফায়ারের সাথে দেখা করেছিলেন যখন আপনি প্রথমবার সর্বজনীন স্ট্যাটিক ভ্যায়েড মেইন(স্ট্রিং[] আর্গস) চালান । অ্যাক্সেস মডিফায়ার।  ব্যক্তিগত, সুরক্ষিত, ডিফল্ট, সর্বজনীন - 4এখন আপনি ইন্টারফেস সম্পর্কে পাঠ অধ্যয়ন করেছেন, এর উদ্দেশ্য আপনার কাছে স্পষ্ট :) সর্বোপরি, ব্যবহারকারীদের কিছু দেওয়ার জন্য পাবলিক মডিফায়ার তৈরি করা হয়েছিল। উদাহরণস্বরূপ, আপনার প্রোগ্রামের ইন্টারফেস। ধরুন আপনি একটি অনুবাদক প্রোগ্রাম লিখেছেন যা রাশিয়ান পাঠ্যকে ইংরেজিতে অনুবাদ করতে পারে। আপনি একটি অনুবাদ (স্ট্রিং টেক্সটইন রুশ) পদ্ধতি তৈরি করেছেন যা সমস্ত প্রয়োজনীয় যুক্তি প্রয়োগ করে। আপনি এই পদ্ধতিটি public শব্দটি দিয়ে চিহ্নিত করেছেন এবং এখন এটি ইন্টারফেসের অংশ:

public class Translator {

   public String translate(String textInRussian) {

       // Translates text from Russian to English
   }
}
আপনি এই পদ্ধতিটিকে স্ক্রিনের 'অনুবাদ' বোতামে আবদ্ধ করতে পারেন এবং আপনার কাজ শেষ! যে কেউ এটি ব্যবহার করতে পারেন. পাবলিক মডিফায়ার দিয়ে চিহ্নিত কোডের অংশগুলি শেষ ব্যবহারকারীর জন্য তৈরি। একটি বাস্তব-জীবনের উদাহরণ প্রদান করে, একটি টিভির অভ্যন্তরে ঘটে এমন সমস্ত প্রক্রিয়ার জন্য ব্যক্তিগত , কিন্তু টিভি পরিচালনা করতে ব্যবহৃত রিমোট কন্ট্রোলের বোতামগুলির জন্য সর্বজনীন । আরও কী, ব্যবহারকারীকে টেলিভিশনটি কীভাবে তৈরি করা হয় বা এটি কীভাবে কাজ করে তা জানার দরকার নেই। রিমোট কন্ট্রোল হল পাবলিক পদ্ধতির সেট : on() , off() , nextChannel() , previousChannel() , increaseVolume() , reduceVolume() ইত্যাদি ।আপনি যা শিখেছেন তা শক্তিশালী করার জন্য, আমরা আপনাকে আমাদের জাভা কোর্স থেকে একটি ভিডিও পাঠ দেখার পরামর্শ দিই
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION