বেনামী ভিতরের ক্লাস, এবং উদাহরণ - 1

"হাই, অ্যামিগো!"

"কিন্তু আমরা ইতিমধ্যে হ্যালো বলেছি, এলি!"

"আরে, আপনার খালার সাথে তর্ক করবেন না। 31 শতকে, আপনি যদি আধা ঘন্টার বেশি কাউকে না দেখে থাকেন তবে আবার হ্যালো বলার রেওয়াজ। তাই আপনার মনোভাব আমাকে দেবেন না!"

"যাইহোক, এটি আরেকটি আকর্ষণীয় বিষয়ের জন্য সময়: রোবট প্রজনন!"

"ও_ও।"

"শুধু মজা করছি, নতুন বিষয় হল বেনামী অভ্যন্তরীণ ক্লাস ।"

"জাভাতে, কখনও কখনও এমন পরিস্থিতি রয়েছে যেখানে আপনাকে বেশ কয়েকটি ক্লাসের উত্তরাধিকারের জন্য একটি ক্লাসের প্রয়োজন হবে৷ যেহেতু জাভা একাধিক উত্তরাধিকার সমর্থন করে না, তাই তারা অভ্যন্তরীণ ক্লাস ব্যবহার করে এই সমস্যার সমাধান করেছে: আমাদের ক্লাসে, আমরা একটি অভ্যন্তরীণ শ্রেণী ঘোষণা করি এবং তৈরি করি এটি উত্তরাধিকার সূত্রে প্রাপ্ত করার জন্য আমাদের যে শ্রেণীর প্রয়োজন তা উত্তরাধিকারসূত্রে পাওয়া যায়। এখানে একটি উদাহরণ:"

একটি অভ্যন্তরীণ শ্রেণীর উদাহরণ যা থ্রেড ক্লাসের উত্তরাধিকারী
class Tiger extends Cat
{
 public void tigerRun()
 {
  .....
 }

 public void startTiger()
 {
  TigerThread thread = new TigerThread();
  thread.start();
 }

 class TigerThread extends Thread
 {
  public void run()
  {
   tigerRun();
  }
 }
}

"আসুন আরেকটি উদাহরণে খনন করা যাক:"

আমাদের থ্রেড ক্লাসের একটি সাবক্লাস দরকার যাতে এটির রান পদ্ধতি ওভাররাইড করা যায়।"

"তাই টাইগার ক্লাসে আমরা TigerThread অভ্যন্তরীণ শ্রেণী ঘোষণা করেছি, যা থ্রেডের উত্তরাধিকারী এবং রান পদ্ধতিকে ওভাররাইড করে।

"সুবিধার জন্য, আমরা টাইগার ক্লাসে দুটি পদ্ধতি সংজ্ঞায়িত করেছি: tigerRun এবং startTiger (যা থ্রেডের রান এবং স্টার্ট পদ্ধতির সাথে সাদৃশ্যপূর্ণ।"

"tigerStart পদ্ধতিতে, আমরা একটি TigerThread অবজেক্ট তৈরি করি এবং এটির start() পদ্ধতি চালু করি।"

"JVM একটি নতুন থ্রেড তৈরি করবে যা টাইগার থ্রেডের রান মেথড বলা হলে চলতে শুরু করবে।"

"এই পদ্ধতিটি তখন আমাদের রান পদ্ধতিকে বলে : tigerRun ।"

"আমি আগে থ্রেডের সাথে কাজ করেছি, তাই এটি সোজা বলে মনে হচ্ছে।"

"আমাদের কি টাইগাররান এবং টাইগারস্টার্ট পদ্ধতির নাম দিতে হবে?"

"না, আমরা তাদের রান এবং শুরু করতে পারতাম, কিন্তু আমি এটাও দেখাতে চেয়েছিলাম যে আমরা থ্রেডের উত্তরাধিকারী নই। একটি ব্যাখ্যা আরও বিভ্রান্তিকর হতে পারে।"

"ঠিক আছে। তারপরে আমি মনে করি আমি এটি পেয়েছি। কিন্তু যদি টাইগারস্টার্টকে দ্বিতীয়বার বলা হয়, আমরা একটি দ্বিতীয় থ্রেড অবজেক্ট তৈরি করব এবং শুরু করব। এর মানে কি এই নয় যে আমাদের "একটি বাঘ দুটি ভিন্ন থ্রেডে চলছে"? "

"আচ্ছা, আপনি কি তীক্ষ্ণ নন! আপনি ঠিক বলেছেন, এবং এটি ভাল নয়। আসুন কোডটি এভাবে আবার লিখি:"

কোড
class Tiger extends Cat
{
 public void tigerRun()
 {
  .....
 }

 public void startTiger()
 {
  thread.start();
 }

 private TigerThread thread = new TigerThread();

 private class TigerThread extends Thread
 {
  public void run()
  {
   tigerRun();
  }
 }
}

"এটি পুরোপুরি নিখুঁত নয়। আপনি এখনও এমন একটি পদ্ধতিকে দুবার কল করতে পারবেন না। কিন্তু এইবার, অন্তত আমরা একটি দ্বিতীয় থ্রেড তৈরি করব না এবং সবকিছু ঠিক আছে বলে মনে করব।"

"এটা ঠিক। দ্বিতীয়বার টাইগার শুরু হলে আপনি ব্যতিক্রম পাবেন।"

"আমি ইতিমধ্যেই আপনার চেয়ে ভুলগুলি ভাল করে দেখছি, এলি!"

"হ্যাঁ, আপনি দুর্দান্ত করছেন। তাহলে আসুন বেনামী ভিতরের ক্লাসে চলে যাই।"

"উপরের কোডের কয়েকটি দিক নোট করুন:"

1) আমরা থ্রেড ক্লাস উত্তরাধিকারসূত্রে পেয়েছি, কিন্তু সেখানে কার্যত কোন কোড প্রয়োগ করিনি। "এটি আরও বেশি ছিল "আমাদের থ্রেড ক্লাসের উত্তরাধিকারী হতে হয়েছিল" বরং "আমরা এটিকে প্রসারিত করার জন্য উত্তরাধিকারসূত্রে পেয়েছি"।

2) শুধুমাত্র একটি TigerThread অবজেক্ট তৈরি করা হবে।

অন্য কথায়, আমরা শুধুমাত্র একটি পদ্ধতি ওভাররাইড করতে এবং একটি অবজেক্ট তৈরি করতে কোডের পুরো গুচ্ছ লিখেছি।

আপনার কি মনে আছে আমি কীভাবে কনস্ট্রাক্টর আবিষ্কারের কথা বলেছিলাম?

কনস্ট্রাক্টরের আগে কনস্ট্রাক্টর পরে
TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}
Thread thread = new Thread()
{
 public void run()
 {
  tigerRun();
 }
};

"আমি দেখছি কোডটি আরও কমপ্যাক্ট হয়ে গেছে, কিন্তু আমি ঠিক বুঝতে পারছি না কি ঘটছে।"

"আমরা চারটি জিনিসকে একত্রিত করতে পারি:"

1) একটি প্রাপ্ত বর্গ ঘোষণা

2) পদ্ধতি ওভাররাইডিং

3) একটি পরিবর্তনশীল ঘোষণা

4) একটি প্রাপ্ত বর্গ একটি উদাহরণ সৃষ্টি.

"আসলে, আমরা যা করছি তা হল দুটি ক্রিয়াকলাপকে একত্রিত করা: একটি প্রাপ্ত বর্গ ঘোষণা করা এবং সেই শ্রেণীর একটি উদাহরণ তৈরি করা।"

বেনামী ক্লাস ছাড়া বেনামী ক্লাসের সাথে
Cat tiger = new Tiger();

class Tiger extends Cat
{
}
Cat tiger = new Cat()
{
};

"আবার সিনট্যাক্স অন্বেষণ করা যাক:"

একটি থ্রেড পরিবর্তনশীল ঘোষণা
Thread thread = new Thread();
একটি ভেরিয়েবলের ঘোষণা যার ধরন হল "একটি বেনামী শ্রেণী যা থ্রেডের উত্তরাধিকারী হয়"
Thread thread = new Thread()
{

};

"মনে রাখবেন যে আমরা কেবল একটি নতুন ক্লাস সংজ্ঞায়িত করছি না। আমরা একটি ভেরিয়েবল তৈরি করছি - শেষে একটি সেমিকোলন আছে!"

"এবং যদি আমরা রান পদ্ধতিটি ওভাররাইড করতে চাই, তাহলে আমাদের এটি লিখতে হবে:"

একটি থ্রেড পরিবর্তনশীল ঘোষণা
Thread thread = new Thread()
{
 public void run()
  {
   System.out.println("new run-method");
  }
};

"আপনি তাড়াতাড়ি ধরুন। ভাল হয়েছে!"

"ধন্যবাদ। আমাদের যদি অন্য পদ্ধতির প্রয়োজন হয় যেগুলো থ্রেড ক্লাসের অংশ নয়?"

"আপনি তাদের লিখতে পারেন।"

"যদিও বেনামী, এটি একটি পূর্ণাঙ্গ অভ্যন্তরীণ শ্রেণী:"

জাভা কোড বর্ণনা
Thread thread = new Thread()
{
  public void run()
  {
   printHi();
  }

  public void printHi()
  {
   System.out.println("Hi!");
  }
};	 
লাল: ভেরিয়েবল তৈরির জন্য কোড।

সবুজ: বস্তু তৈরির জন্য কোড।

নীল: বেনামী প্রাপ্ত শ্রেণীর জন্য কোড।

"একটি পূর্ণাঙ্গ অভ্যন্তরীণ শ্রেণী?"

"তাহলে আমি বাইরের শ্রেণীর ভেরিয়েবল ব্যবহার করতে পারি?"

"একেবারে।"

"এবং আমি কনস্ট্রাক্টরের কাছে কিছু দিতে পারি?"

"হ্যাঁ, কিন্তু শুধুমাত্র সুপারক্লাসের কনস্ট্রাক্টরের জন্য আর্গুমেন্ট:"

ক্লাস একটি বেনামী অভ্যন্তরীণ শ্রেণীর উদাহরণ
class Cat
{
 int x, y;
 Cat(int x, int y)
 {
  this.x = x;
  thix.y = y;
 }
}
Cat cat = new Cat(3,4)
{
  public void print()
  {
   System.out.println(x+" "+y);
  }
};

"আমরা অন্য কারো কনস্ট্রাক্টরে আমাদের নিজস্ব প্যারামিটার যোগ করতে পারি না। কিন্তু আমরা বাইরের ক্লাসের ভেরিয়েবল ব্যবহার করতে পারি, যা এই ঘাটতির জন্য সুন্দরভাবে ক্ষতিপূরণ দেয়।"

"যদি আমাকে এখনও কনস্ট্রাক্টরে অন্যান্য পরামিতি যোগ করতে হয়?"

"তারপর একটি সাধারণ (অনামী) অভ্যন্তরীণ শ্রেণী ঘোষণা করুন এবং এটি ব্যবহার করুন।"

"ঠিক আছে, আমি প্রায় ভুলে গেছি।"

"যদি আমি একটি স্ট্যাটিক ভেরিয়েবল ঘোষণা করি? তাহলে কি বেনামী ক্লাসটি একটি অভ্যন্তরীণ শ্রেণীর পরিবর্তে একটি স্ট্যাটিক নেস্টেড শ্রেণীতে পরিণত হবে? অন্য কথায়, এটির বাইরের শ্রেণীর একটি রেফারেন্সের অভাব হবে?"

"না। এটি একটি বেনামী অভ্যন্তরীণ শ্রেণী হবে। এই উদাহরণগুলি দেখুন।"

বেনামী ক্লাসের সাথে বেনামী ক্লাস ছাড়া
Thread thread = new Thread()
{
  public void run()
  {
   tigerRun();
  }
};
TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}
static Thread thread = new Thread()
{
  public void run()
  {
   tigerRun();
  }
};
static TigerThread thread = new TigerThread();

private class TigerThread extends Thread
{
 public void run()
 {
  tigerRun();
 }
}

"আমি দেখতে পাচ্ছি। শুধুমাত্র স্ট্যাটিক ভেরিয়েবল স্ট্যাটিক হবে, ক্লাস নয়।"

"হ্যাঁ।"

"আসলে, কম্পাইলার সমস্ত বেনামী অভ্যন্তরীণ ক্লাসের জন্য অভ্যন্তরীণ ক্লাস তৈরি করে। এই ক্লাসগুলিকে সাধারণত «1», «2», «3», ইত্যাদি নাম দেওয়া হয়।