1. টাইপকাস্টিং

যে ভেরিয়েবলগুলি রেফারেন্স প্রকার (ক্লাস) সঞ্চয় করে সেগুলিও বিভিন্ন প্রকারে রূপান্তরিত হতে পারে। কিন্তু এটি শুধুমাত্র একটি একক ধরনের অনুক্রমের মধ্যে কাজ করে। এর একটি সহজ উদাহরণ তাকান. ধরুন আমাদের নিম্নোক্ত শ্রেণী শ্রেণিবিন্যাস আছে, যেখানে নিচের শ্রেণীগুলো উপরের ক্লাসের উত্তরাধিকারী।

টাইপকাস্টিং

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

আমরা দেখতে পাই যে বিড়াল শ্রেণী পোষ্য শ্রেণীর উত্তরাধিকারী হয়, এবং পোষা শ্রেণী, পরিবর্তে, পশু শ্রেণীর উত্তরাধিকারী হয়।

যদি আমরা এই মত কোড লিখি:

Animal kitten = new Cat();

এটি একটি প্রসারিত টাইপ রূপান্তর । একে অন্তর্নিহিত কাস্টও বলা হয়। আমরা বিড়ালের রেফারেন্সটি প্রশস্ত করেছি যাতে এটি এখন একটি বিড়াল বস্তুকে বোঝায়। এই ধরনের টাইপ কনভার্সন দিয়ে, আমরা ক্যাট ক্লাসে উপস্থিত কিন্তু অ্যানিমাল ক্লাসে অনুপস্থিত কল পদ্ধতিতে বিড়ালছানার রেফারেন্স ব্যবহার করতে পারব না ।

একটি সংকীর্ণ রূপান্তর (বা স্পষ্ট কাস্ট) বিপরীত দিকে ঘটে:

Cat cat = (Cat) kitten;

আমরা স্পষ্টভাবে ইঙ্গিত করেছি যে আমরা বিড়ালছানা ভেরিয়েবলে সংরক্ষিত রেফারেন্সকে (যার ধরন হল Animal ) বিড়ালের ধরণে কাস্ট করতে চাই৷



2. একটি বস্তুর ধরন পরীক্ষা করা হচ্ছে

কিন্তু এখানে আপনাকে খুব সাবধানে থাকতে হবে। আপনি যদি এটি করেন:

Animal beast = new Cat();
Wolf grayWolf = (Wolf) beast;

কম্পাইলার এই কোড অনুমোদন করবে, কিন্তু প্রোগ্রাম রান করার সময় একটি ত্রুটি হবে ! JVM একটি ব্যতিক্রম নিক্ষেপ করবে:

Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to a Wolf

একটি বিড়াল বস্তুর উল্লেখ শুধুমাত্র ভেরিয়েবলে সংরক্ষণ করা যেতে পারে যার ধরনটি বিড়াল শ্রেণীর পূর্বপুরুষ: পোষা প্রাণী, বা বস্তু।

কেন এমন হল?

এখানে প্রাসঙ্গিক বিষয় হল যে একটি বস্তুর রেফারেন্স সেই বস্তুর পদ্ধতি এবং ভেরিয়েবলগুলি উল্লেখ করতে ব্যবহৃত হয় । এবং কোনও সমস্যা হবে না যদি আমরা একটি বিড়াল বস্তুর একটি রেফারেন্স সংরক্ষণ করার জন্য একটি প্রাণী ভেরিয়েবল ব্যবহার করি: বিড়ালের প্রকারের সর্বদা প্রাণীর প্রকারের একটি ভেরিয়েবল এবং পদ্ধতি থাকে - এটি তাদের উত্তরাধিকারসূত্রে পেয়েছে!

কিন্তু যদি JVM আমাদেরকে একটি উলফ ভেরিয়েবলে একটি ক্যাট অবজেক্টের রেফারেন্স সংরক্ষণ করার অনুমতি দেয়, তাহলে আমাদের এমন একটি পরিস্থিতি হতে পারে যেখানে আমরা সেই ভেরিয়েবলে সংরক্ষিত Cat অবজেক্টে বিদ্যমান নেই এমন একটি পদ্ধতিকে কল করার জন্য grayWolf ভেরিয়েবল ব্যবহার করার চেষ্টা করতে পারি। . সেজন্য এই আয়োজনের অনুমতি নেই।

জাভাতে একটি বিশেষ instanceofঅপারেটর রয়েছে যা আপনাকে একটি বস্তু একটি নির্দিষ্ট ধরণের কিনা তা পরীক্ষা করতে দেয় এবং তাই একটি নির্দিষ্ট ধরণের ভেরিয়েবলে সংরক্ষণ করা যেতে পারে। এটা বেশ সহজ দেখায়:

variable instanceof Type

উদাহরণ:

Animal beast = new Cat();
if (beast instanceof Wolf)
{
   Wolf grayWolf = (Wolf) beast;
}

এই কোডটি ত্রুটি সৃষ্টি করবে না — এমনকি রানটাইমেও।

এখানে আরও কিছু উদাহরণ রয়েছে যা পরিস্থিতিকে চিত্রিত করে:

প্রসারিত টাইপ রূপান্তর বর্ণনা
Cow cow = new Whale();

এটি একটি ক্লাসিক প্রশস্তকরণ রূপান্তর — কোন প্রকার রূপান্তর অপারেটরের প্রয়োজন নেই৷ এখন কেবলমাত্র ক্লাসে সংজ্ঞায়িত পদ্ধতিগুলিকে Cowঅবজেক্টে কল করা যেতে পারে Whale

ভেরিয়েবলে , কম্পাইলার আপনাকে শুধুমাত্র সেই পদ্ধতিগুলি কল করতে দেবে যা এর ধরন (শ্রেণীর cow)Cow আছে।

সংকীর্ণ টাইপ রূপান্তর
Cow cow = new Whale();
if (cow instanceof Whale)
{
   Whale whale = (Whale) cow;
}
ক্লাসিক সংকীর্ণ রূপান্তর: আপনাকে একটি টাইপ চেক এবং একটি কাস্ট অপারেটর যোগ করতে হবে।
ভেরিয়েবল Cow cowএকটি বস্তুর একটি রেফারেন্স সংরক্ষণ করে Whale
আমরা যাচাই করি যে এটিই হয় , এবং তারপর একটি (সংকীর্ণ) টাইপ রূপান্তর সম্পাদন করি। বা এটিও বলা হয়:
একটি টাইপ কাস্ট
.

Cow cow = new Cow();
Whale whale = (Whale) cow; // Exception
আপনি বস্তুর ধরন পরীক্ষা না করে একটি রেফারেন্স টাইপ সংকীর্ণ করতে পারেন।
যদি cowভেরিয়েবলটি এমন একটি বস্তুকে বোঝায় যা a নয় Whale, তাহলে একটি InvalidClassCastExceptionতৈরি হবে।


3. কলিং মূল পদ্ধতি: superকীওয়ার্ড

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

আমরা যদি আমাদের পদ্ধতিতে প্যারেন্ট ক্লাসের পদ্ধতিটি করতে পারি এবং তারপরে আমাদের নিজস্ব কিছু কোড চালাতে পারি তবে এটি দুর্দান্ত হবে। অথবা সম্ভবত প্রথমে আমাদের নিজস্ব কোড এক্সিকিউট করুন এবং তারপর প্যারেন্ট ক্লাসের পদ্ধতিতে কল করুন।

এবং জাভা আমাদের দেয় ঠিক যে. অভিভাবক শ্রেণীর একটি পদ্ধতি কল করতে, এটি করুন:

super.method(arguments);

উদাহরণ:

class PeaceTime
{
   public double getPi()
   {
      return 3.14;
   }
}

class WarTime extends PeaceTime
{
   public double getPi()
   {
      return super.getPi()*2;  // 3.14*2
   }
}

যুদ্ধকালীন সময়ে এর মান Pi৬-এর বেশি হতে পারে! অবশ্যই, আমরা মজা করছি, কিন্তু এই উদাহরণটি দেখায় কিভাবে এই সব কাজ করতে পারে।

বিষয়গুলিকে কিছুটা স্পষ্ট করার জন্য এখানে আরও কয়েকটি উদাহরণ রয়েছে:

কোড বর্ণনা
class Cow
{
   public void printAll()
   {
      printColor();
      printName();
   }

   public void printColor()
   {
      System.out.println("I'm a white whale");
   }

   public void printName()
   {
      System.out.println("I'm a cow");
   }
}

class Whale extends Cow
{
   public void printName()
   {
      System.out.print("This is incorrect: ");
      super.printName();
      System.out.println("I'm a whale");
   }
}
Cowএবং Whaleক্লাস
public static void main(String[] args)
{
   Whale whale = new Whale();
   whale.printAll();
}
পর্দার আউটপুট হবে:
I'm a white whale
This is incorrect: I'm a cow
I'm a whale

এই কঠিন জিনিস. সত্যি বলতে, এটি OOP- এর সবচেয়ে কঠিন জিনিসগুলির মধ্যে একটি । যে বলেছে, আপনার এটি জানতে এবং বুঝতে হবে।