1. ভেরিয়েবল শুরু করা

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

এবং এই একই ভেরিয়েবলগুলি একটি কনস্ট্রাক্টরেও শুরু করা যেতে পারে। এর মানে হল যে, তত্ত্বগতভাবে, এই ভেরিয়েবলগুলিকে দুইবার মান নির্ধারণ করা যেতে পারে। উদাহরণ

কোড বিঃদ্রঃ
class Cat
{
   public String name;
   public int age = -1;

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

   public Cat()
   {
     this.name = "Nameless";
   }
}



ভেরিয়েবলটিকে ageএকটি প্রাথমিক মান নির্ধারণ করা হয়েছে




প্রাথমিক মানটি ওভাররাইট করা হয়েছে


বয়সের পরিবর্তনশীলটি তার প্রাথমিক মান সংরক্ষণ করে।
Cat cat = new Cat("Whiskers", 2);
এটি অনুমোদিত: প্রথম কনস্ট্রাক্টরকে ডাকা হবে
Cat cat = new Cat();
এটি অনুমোদিত: দ্বিতীয় কনস্ট্রাক্টরকে ডাকা হবে

যখন মৃত্যুদন্ড কার্যকর করা হয় তখন এটি ঘটে Cat cat = new Cat("Whiskers", 2);:

  • একটি Catবস্তু তৈরি হয়
  • সমস্ত দৃষ্টান্ত ভেরিয়েবল তাদের প্রাথমিক মান দিয়ে শুরু করা হয়
  • কনস্ট্রাক্টরকে বলা হয় এবং এর কোডটি কার্যকর করা হয়।

অন্য কথায়, ভেরিয়েবলগুলি প্রথমে তাদের প্রাথমিক মানগুলি পায়, এবং শুধুমাত্র তখনই কনস্ট্রাক্টরের কোডটি কার্যকর করা হয়।


2. একটি ক্লাসে ভেরিয়েবলের আরম্ভ করার ক্রম

ভেরিয়েবলগুলি শুধুমাত্র কনস্ট্রাক্টর চালানোর আগে শুরু করা হয় না - সেগুলি একটি সু-সংজ্ঞায়িত ক্রমে শুরু হয়: যে ক্রমে সেগুলি ক্লাসে ঘোষণা করা হয়।

আসুন কিছু আকর্ষণীয় কোড দেখুন:

কোড বিঃদ্রঃ
public class Solution
{
   public int a = b + c + 1;
   public int b = a + c + 2;
   public int c = a + b + 3;
}

এই কোডটি কম্পাইল করা হবে না, যেহেতু ভেরিয়েবলটি তৈরি করার সময়  এখনও কোন  এবং ভেরিয়েবল aনেই । কিন্তু আপনি নিচের মত করে আপনার কোড লিখতে পারেন — এই কোড কম্পাইল হবে এবং ঠিকই চলবে ।bc

কোড বিঃদ্রঃ
public class Solution
{
   public int a;
   public int b = a + 2;
   public int c = a + b + 3;
}


0
0+2
0+2+3

কিন্তু মনে রাখবেন যে আপনার কোড অবশ্যই অন্যান্য বিকাশকারীদের কাছে স্বচ্ছ হতে হবে। এই ধরনের কৌশল ব্যবহার না করাই ভালো, কারণ এটি কোডের পঠনযোগ্যতাকে ক্ষতিগ্রস্ত করে।

এখানে আমাদের অবশ্যই মনে রাখতে হবে যে ভেরিয়েবলগুলিকে একটি মান নির্ধারণ করার আগে তাদের একটি ডিফল্ট মান থাকে। প্রকারের জন্য int, এটি শূন্য।

যখন JVM ভেরিয়েবলটিকে আরম্ভ করে a, তখন এটি কেবলমাত্র int টাইপের জন্য ডিফল্ট মান নির্ধারণ করবে: 0।

যখন এটি পৌঁছাবে b, একটি ভেরিয়েবল ইতিমধ্যেই পরিচিত হবে এবং একটি মান থাকবে, তাই JVM এটিকে 2 মান নির্ধারণ করবে।

এবং যখন এটি cভেরিয়েবলে পৌঁছাবে, aএবং bভেরিয়েবলগুলি ইতিমধ্যেই শুরু হবে, তাই JVM সহজেই প্রাথমিক মান গণনা করবে c: 0+2+3।

আপনি যদি একটি পদ্ধতির মধ্যে একটি ভেরিয়েবল তৈরি করেন তবে আপনি এটি ব্যবহার করতে পারবেন না যদি না আপনি এটিতে একটি মান নির্ধারণ করেন। কিন্তু এটি একটি শ্রেণীর ভেরিয়েবলের জন্য সত্য নয়! যদি একটি প্রাথমিক মান একটি ক্লাসের একটি ভেরিয়েবলে বরাদ্দ না করা হয়, তাহলে এটি একটি ডিফল্ট মান নির্ধারণ করা হয়।


3. ধ্রুবক

যখন আমরা বিশ্লেষণ করছি কিভাবে বস্তু তৈরি করা হয়, এটি ধ্রুবকের প্রারম্ভিকতা, অর্থাৎ পরিবর্তনকারীর সাথে ভেরিয়েবলের উপর স্পর্শ করা মূল্যবান final

যদি একটি ভেরিয়েবলের finalসংশোধক থাকে, তাহলে অবশ্যই একটি প্রাথমিক মান নির্ধারণ করতে হবে। আপনি ইতিমধ্যে এটি জানেন, এবং এটি সম্পর্কে অবাক হওয়ার কিছু নেই।

কিন্তু আপনি যা জানেন না তা হল আপনি যদি কনস্ট্রাক্টরে এটি বরাদ্দ করেন তবে আপনাকে এখনই প্রাথমিক মান নির্ধারণ করতে হবে না। এটি একটি চূড়ান্ত ভেরিয়েবলের জন্য ঠিক কাজ করবে। শুধুমাত্র প্রয়োজন হল যে আপনার যদি একাধিক কনস্ট্রাক্টর থাকে, তাহলে প্রতিটি কনস্ট্রাক্টরে একটি চূড়ান্ত ভেরিয়েবলকে একটি মান বরাদ্দ করতে হবে।

উদাহরণ:

public class Cat
{
   public final int maxAge = 25;
   public final int maxWeight;

   public Cat (int weight)
   {
     this.maxWeight = weight; // Assign an initial value to the constant
   }
}


4. একটি কন্সট্রাক্টরে কোড

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

উদাহরণস্বরূপ, এখানে কনস্ট্রাক্টর সম্পর্কে একটি গুরুত্বপূর্ণ মন্তব্য। তাত্ত্বিকভাবে, আপনি একটি কনস্ট্রাক্টরে যেকোনো জটিলতার কোড লিখতে পারেন। কিন্তু এটা করবেন না। উদাহরণ:

class FilePrinter
{
   public String content;

   public FilePrinter(String filename) throws Exception
   {
      FileInputStream input = new FileInputStream(filename);
      byte[] buffer = input.readAllBytes();
      this.content = new String(buffer);
   }

   public void printFile()
   {
      System.out.println(content);
   }
}






একটি ফাইল রিড স্ট্রিম খুলুন
একটি বাইট অ্যারে ফাইলটি পড়ুন
একটি স্ট্রিং হিসাবে বাইট অ্যারে সংরক্ষণ করুন




পর্দায় ফাইলের বিষয়বস্তু প্রদর্শন করুন

ফাইলপ্রিন্টার ক্লাস কনস্ট্রাক্টরে, আমরা অবিলম্বে একটি ফাইলে একটি বাইট স্ট্রিম খুলি এবং এর বিষয়বস্তু পড়ি। এটি জটিল আচরণ এবং এর ফলে ত্রুটি হতে পারে।

এরকম কোন ফাইল না থাকলে কি হতো? ফাইল পড়তে সমস্যা হলে কি হবে? এটা খুব বড় হলে কি হবে?

জটিল যুক্তি ত্রুটির উচ্চ সম্ভাবনা বোঝায় এবং এর মানে কোডটি অবশ্যই ব্যতিক্রমগুলি সঠিকভাবে পরিচালনা করতে হবে।

উদাহরণ 1 — সিরিয়ালাইজেশন

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

কিন্তু তারপর ধরুন আপনার ফাইলটি অন্য কম্পিউটারে বিদ্যমান নেই। কনস্ট্রাক্টরের মধ্যে একটি ত্রুটি থাকবে, এবং কেউ এটি পরিচালনা করবে না। এবং এটি প্রোগ্রামটি বন্ধ করতে যথেষ্ট সক্ষম।

উদাহরণ 2 — একটি ক্লাসের ক্ষেত্র শুরু করা

যদি আপনার ক্লাস কনস্ট্রাক্টর চেক করা ব্যতিক্রমগুলি নিক্ষেপ করতে পারে, যেমন থ্রোস কীওয়ার্ড দিয়ে চিহ্নিত করা হয়, তাহলে আপনাকে অবশ্যই আপনার অবজেক্ট তৈরি করার পদ্ধতিতে নির্দেশিত ব্যতিক্রমগুলি ধরতে হবে।

কিন্তু যদি এমন কোন পদ্ধতি না থাকে? উদাহরণ:

কোড  বিঃদ্রঃ
class Solution
{
   public FilePrinter reader = new FilePrinter("c:\\readme.txt");
}
এই কোড কম্পাইল হবে না.

ক্লাস FilePrinterকনস্ট্রাক্টর একটি চেক করা ব্যতিক্রম ছুঁড়ে দিতে পারে , যার মানে আপনি FilePrinterএকটি ট্রাই-ক্যাচ ব্লকে মোড়ানো ছাড়া একটি বস্তু তৈরি করতে পারবেন না। এবং একটি চেষ্টা-ক্যাচ ব্লক শুধুমাত্র একটি পদ্ধতিতে লেখা যেতে পারে



5. বেস ক্লাস কনস্ট্রাক্টর

পূর্ববর্তী পাঠে, আমরা উত্তরাধিকার নিয়ে একটু আলোচনা করেছি। দুর্ভাগ্যবশত, উত্তরাধিকার এবং OOP সম্পর্কে আমাদের সম্পূর্ণ আলোচনা OOP-এর জন্য নিবেদিত স্তরের জন্য সংরক্ষিত, এবং কনস্ট্রাক্টরদের উত্তরাধিকার ইতিমধ্যেই আমাদের জন্য প্রাসঙ্গিক।

যদি আপনার ক্লাসটি অন্য ক্লাসের উত্তরাধিকারী হয়, তাহলে অভিভাবক শ্রেণীর একটি বস্তু আপনার ক্লাসের একটি বস্তুর মধ্যে এমবেড করা হবে। আরও কী, প্যারেন্ট ক্লাসের নিজস্ব ভেরিয়েবল এবং নিজস্ব কনস্ট্রাক্টর রয়েছে।

এর মানে হল যে আপনার ক্লাসের একটি প্যারেন্ট ক্লাস থাকলে এবং আপনি এর ভেরিয়েবল এবং পদ্ধতিগুলিকে উত্তরাধিকার সূত্রে প্রাপ্ত হলে কীভাবে ভেরিয়েবল শুরু করা হয় এবং কনস্ট্রাক্টর বলা হয় তা জানা এবং বোঝা আপনার জন্য খুবই গুরুত্বপূর্ণ।

ক্লাস

ভেরিয়েবল শুরু করা হয় এবং কনস্ট্রাক্টর বলা হয় তা আমরা কিভাবে জানি? দুটি ক্লাসের জন্য কোড লিখে শুরু করা যাক। একজন অন্যটি উত্তরাধিকারী হবে:

কোড বিঃদ্রঃ
class ParentClass
{
   public String a;
   public String b;

   public ParentClass()
   {
   }
}

class ChildClass extends ParentClass
{
   public String c;
   public String d;

   public ChildClass()
   {
   }
}










ক্লাস ChildClass উত্তরাধিকারসূত্রে পায় ParentClass

ভেরিয়েবল শুরু করা হয় এবং কনস্ট্রাক্টর বলা হয় সেই ক্রমটি আমাদের নির্ধারণ করতে হবে। লগিং আমাদের এটি করতে সাহায্য করবে।

লগিং

লগিং হল একটি প্রোগ্রামের দ্বারা সঞ্চালিত ক্রিয়াগুলিকে কনসোল বা ফাইলে লিখে রেকর্ড করার প্রক্রিয়া।

কনস্ট্রাক্টরকে বলা হয়েছে তা নির্ধারণ করা বেশ সহজ: কনস্ট্রাক্টরের শরীরে, কনসোলে একটি বার্তা লিখুন। কিন্তু কিভাবে আপনি বলতে পারেন যদি একটি পরিবর্তনশীল শুরু করা হয়েছে?

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

চূড়ান্ত কোড

public class Main
{
   public static void main(String[] args)
   {
      ChildClass obj = new ChildClass();
   }

   public static String print(String text)
   {
      System.out.println(text);
      return text;
   }
}

class ParentClass
{
   public String a = Main.print("ParentClass.a");
   public String b = Main.print("ParentClass.b");

   public ParentClass()
   {
      Main.print("ParentClass.constructor");
   }
}

class ChildClass extends ParentClass
{
   public String c = Main.print("ChildClass.c");
   public String d = Main.print("ChildClass.d");

   public ChildClass()
   {
      Main.print("ChildClass.constructor");
   }
}




একটি ChildClassঅবজেক্ট তৈরি করুন


এই পদ্ধতিটি পাস করা টেক্সট কনসোলে লেখে এবং ফেরত দেয়। ক্লাস ডিসপ্লে টেক্সট





ঘোষণা করুন এবং এটি দিয়ে ভেরিয়েবল শুরু করুন। কনস্ট্রাক্টরকে বলা হয়েছে এমন একটি বার্তা লিখুন। রিটার্ন মান উপেক্ষা করুন. ক্লাস ডিসপ্লে টেক্সট ঘোষণা করুন এবং এটি দিয়ে ভেরিয়েবল শুরু করুন। কনস্ট্রাক্টরকে বলা হয়েছে এমন একটি বার্তা লিখুন। রিটার্ন মান উপেক্ষা করুন. ParentClass









ChildClass






আপনি যদি এই কোডটি কার্যকর করেন, পাঠ্যটি স্ক্রিনে নিম্নরূপ প্রদর্শিত হবে:

পদ্ধতির কনসোল আউটপুটMain.print()
ParentClass.a
ParentClass.b
ParentClass.constructor
ChildClass.c
ChildClass.d
ChildClass.constructor

সুতরাং আপনি সর্বদা ব্যক্তিগতভাবে নিশ্চিত করতে পারেন যে কন্সট্রাক্টরকে কল করার আগে একটি ক্লাসের ভেরিয়েবলগুলি আরম্ভ করা হয়েছে। উত্তরাধিকারসূত্রে প্রাপ্ত ক্লাস শুরু হওয়ার আগে একটি বেস ক্লাস সম্পূর্ণরূপে শুরু হয়।