Thursday, October 12, 2017

C# For Beginners , Part-23 (Polymorphism)

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

using System;

public class Employee
{
    public string FirstName="Naim";
    public string LastName="Shahriar";
   
   
    public void printFullName()
    {
       
        Console.WriteLine(FirstName + " " + LastName);
    }
}
public class PartTimeEmployee:Employee
{
  
}
public class FulltimeEmployee:Employee
{

}
public class TemporaryEmployee : Employee
{

}

    class Program
    {
        static void Main()

        {
            Employee[] employees = new Employee[3];
            employees[0] = new FulltimeEmployee();
            employees[1] = new PartTimeEmployee();
            employees[2] = new TemporaryEmployee();
            for (int i = 0; i < 3;i++ )
            {
                employees[i].printFullName();
            }
                Console.ReadKey();
        }
    }

কোড'টি রান করাও ।। আচ্ছা , আমরা এখন বুঝার ট্রাই করি - এখানে কি কি আমরা করলাম ???????
Employee[] employees = new Employee[3]; এর মাধ্যমে আমরা প্রথমবারের মতো অবজেক্ট এর সাথে অ্যারে নিয়ে কাজ করছি ।।এর আগে ,আমরা শুধু একটা ভ্যারিয়েবল নিয়ে কাজ করেছি , তাই এই বিষয়টি তোমাদের কাছে নতুন লাগতে পারে , একটু অস্বস্তিও লাগতে পারে ।। আসলে আমরা যদি Employee ক্লাসের তিন তিন'টা আলাদা আলাদা ( রেফারেন্স  )ভ্যারিয়েবল ক্রিয়েট করে , তাতে আলাদা আলাদা করে চাইল্ড ক্লাসের অব্জেক্ট গুলো অ্যাসাইন করে দিতাম , তাহলে বিষয়টা বুঝতে তোমাদের সহজ হতো ।।
যাই হোক ,একটু সুবিধার্থে আমরা তিন তিন বার কষ্ট করে না লিখে একেবারে  অ্যারেই ক্রিয়েট করে ফেললাম ।। আশা করি , এইবার তোমাদের অস্বস্তি কিছুটা কমেছে ।। আর , আমরা তো জানিই যে - প্যারেন্ট ক্লাস এর অব্জেক্ট এর সাথে চাইল্ড ক্লাসের অব্জেক্টগুলো অ্যাসাইন করা যায় , সেটাই করেছি ।। তারপর একটি ফর লুপ খাটিয়ে সেটাই প্রিন্ট করিয়েছি ।।

আচ্ছা , এখন আমরা যদি প্রত্যেকটা আলাদা আলাদা চাইল্ড ক্লাসের জন্য আলাদা আলাদা স্পেসিফিক জিনিস প্রিন্ট করাতে চাই , তাহলে চলো তো দেখি নীচের কোড কাজ করে  কি না ??

using System;

public class Employee
{
    public string FirstName="Naim";
    public string LastName="Shahriar";
   
   
    public  void printFullName()
    {
       
        Console.WriteLine(FirstName + " " + LastName);
    }
}
public class PartTimeEmployee:Employee
{
    public  void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" PartTime");
    }
}
public class FulltimeEmployee:Employee
{
    public  void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" FullTime");
    }
}
public class TemporaryEmployee : Employee
{
    public  void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" Temporary");
    }
}

    class Program
    {
        static void Main()

        {
            Employee[] employees = new Employee[3];
            employees[0] = new FulltimeEmployee();
            employees[1] = new PartTimeEmployee();
            employees[2] = new TemporaryEmployee();
            for (int i = 0; i < 3;i++ )
            {
                employees[i].printFullName();
            }
                Console.ReadKey();
        }
    }

আচ্ছা , কোড'টি রান করবার আগে , একবার ভাবো তো -- এটা কি আমাদের প্রত্যাশিত আওউটপুট দিবে ???? অবশ্যই দিবে না ।। কেনো , আমরা সব চাইল্ড ক্লাসের অবজেক্টগুলোকে প্যারেন্ট ক্লাসের ভ্যারিয়েবলের সাথে অ্যাসাইন করে দিয়েছি ।। সো , এটা অবশ্যই কাজ করবে না , বুঝতেই পারছো --এর আগের পর্বে আলোচনা করেছি ।। তাহলে কি করা যায় ??? হুম , প্রত্যেকটি আলাদা আলাদা চাইল্ড ক্লাসের জন্য জন্য আলাদা আলাদা করে অবজেক্ট ক্রিয়েট করে প্যারেন্ট ক্লাসের অবজেক্ট এর ( রেফারেন্স ) ভ্যারিয়েবল এর সাথে অ্যাসাইন না করিয়ে কাজ করলেই প্রত্যাশিত আউটপুট পাবো ।। একবার নিজে ট্রাই করে দেখো ।।

কিন্তু , আমি আলাদা আলাদা করে , অবজেক্ট ক্রিয়েট না করেই , এইভাবেই কাজ করাতে চাচ্ছি ।। তাহলে কিছু করা যায় কি না ??/ চলো সেটা দেখে আসি --- নীচের কোডে ----------

using System;

public class Employee
{
    public string FirstName="Naim";
    public string LastName="Shahriar";
   
   
    public virtual void printFullName()
    {
       
        Console.WriteLine(FirstName + " " + LastName);
    }
}
public class PartTimeEmployee:Employee
{
    public override void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" PartTime");
    }
}
public class FulltimeEmployee:Employee
{
    public override void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" FullTime");
    }
}
public class TemporaryEmployee : Employee
{
    public override void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" Temporary");
    }
}

    class Program
    {
        static void Main()

        {
            Employee[] employees = new Employee[3];
            employees[0] = new FulltimeEmployee();
            employees[1] = new PartTimeEmployee();
            employees[2] = new TemporaryEmployee();
            for (int i = 0; i < 3;i++ )
            {
                employees[i].printFullName();
            }
                Console.ReadKey();
        }
    }

আচ্ছা , তাহলে এখানে কি হচ্ছে ??? আমরা প্যারেন্ট ক্লাসে একটা -  virtual কিওয়ারড ইউজ করে সকল চাইল্ড ক্লাসের মেথোডকে এই প্যারেন্ট ক্লাসের সেইম মেথোড এর উপর ওভাররাইড করার অ্যাকসেস দিচ্ছি । আর , চাইল্ড ক্লাস এর মেথোডগুলোকে override কিওয়ারড করে প্যারেন্ট ক্লাসের সেইম মেথোড ওপর ওভাররাইড করবার অনুমুতি দিলাম ।।

এই কারনে , আমরা যতোই প্যারেন্ট ক্লাস Employee এর অব্জেক্ট এর ( রেফারেন্স ) ভ্যারিয়েবল গুলো'তে চাইল্ড ক্লাসগুলো অ্যাসাইন দিচ্ছি না কেনো ,ওভাররাইডের ফলে চাইল্ডক্লাস এর মেথোডগুলোর কাজ চালিয়ে যাচ্ছি ।। এখন তোমাদের মনের থেকে একটা কনফিউজ দূর করতে চাই , সেটা কি ??? সেই আগের মেথোড হাইডের মতো যদি - new কিওয়ারড চাইল্ড ক্লাসগুলোতে ব্যবহার করি , তাহলে কি আসলে প্যারেন্টস ক্লাসের  মেথোড হাইড হবে ?? চলো , দেখে নেই ----

using System;

public class Employee
{
    public string FirstName="Naim";
    public string LastName="Shahriar";
   
   
    public void printFullName()
    {
       
        Console.WriteLine(FirstName + " " + LastName);
    }
}
public class PartTimeEmployee:Employee
{
    public new void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" PartTime");
    }
}
public class FulltimeEmployee:Employee
{
    public new void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" FullTime");
    }
}
public class TemporaryEmployee : Employee
{
    public new void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" Temporary");
    }
}

    class Program
    {
        static void Main()

        {
            Employee[] employees = new Employee[3];
            employees[0] = new FulltimeEmployee();
            employees[1] = new PartTimeEmployee();
            employees[2] = new TemporaryEmployee();
            for (int i = 0; i < 3;i++ )
            {
                employees[i].printFullName();
            }
                Console.ReadKey();
        }
    }

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

কিন্তু , মেথোড ওভাররাইডের ক্ষেত্রে -  আমরা যতোই সব চাইল্ড ক্লাসগুলোর অব্জেক্টগুলোই প্যারেন্ট ক্লাসের অব্জেক্ট এর ( রেফারেন্স ) ভ্যারিয়েবল এর সাথে অ্যাসাইন করে দেই না কেনো ,প্যারেন্ট ক্লাসে এর মেথোডে virtual & চাইল্ড ক্লাসেীর মেথোডে override ইউজ করেই মেথোড হাইড করতে পারছি , শুদ্ধ ভাষায় বলতে গেলে মেথোড ওভাররাইড করতে পারছি ।।  আশা করি , এই মেথোড হাইড এবং মেথোড ওভাররাইড কে কখনো গুলিয়ে ফেলো না , বিষয়টি ক্লিয়ার না হলে - এই কথাটুকু বার বার পড়ো  ।।

তাহলে , আমি এই যে ডিরাইভড ক্লাস এর মেথোডগুলোকে প্যারেন্ট ক্লাস  এর মেথোড এর ওপর ওভাররাইড করার ক্ষমতা দিচ্ছি , এই ঘটনাগুলোকে প্রোগ্রামের ব্যকরণে  পলিমারফিজম বলে ।।

আচ্ছা ধরো , আমি যদি --- প্যারেন্ট ক্লাস এর মেথোড'কে অ্যাকসেস করার জন্য virtual কিওয়ারড ইউজ করলাম , বাট কিন্তু চাইল্ড ক্লাস এর মেথোডকে ওভাররাইড করবার জন্য override ইউজ করলাম না ও অনুমুতি না দেই । তাহলে কি হবে ?? চলো কোড দেখে আসি -------------

using System;

public class Employee
{
    public string FirstName="Naim";
    public string LastName="Shahriar";
   
   
    public virtual void printFullName()
    {
       
        Console.WriteLine(FirstName + " " + LastName);
    }
}
public class PartTimeEmployee:Employee
{
    public override void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName + " PartTime");
    }
}
public class FulltimeEmployee:Employee
{
    public override void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" FullTime");
    }
}
public class TemporaryEmployee : Employee
{
    public  void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" Temporary");
    }
}

    class Program
    {
        static void Main()

        {
            Employee[] employees = new Employee[3];
            employees[0] = new FulltimeEmployee();
            employees[1] = new PartTimeEmployee();
            employees[2] = new TemporaryEmployee();
            for (int i = 0; i < 3;i++ )
            {
                employees[i].printFullName();
            }
                Console.ReadKey();
        }
    }

কোড রান করে দেখো , কি হয় ???  প্যারেন্টস ক্লাসের মেথোড কল করবে , যদি তুমি চাইল্ড ক্লাস এর মেথোড'কে
অনুমুতি না দাও ।। অনুরুপভাবে , আমি যদি চাইল্ড ক্লাসে কোনো মেথোডই না লিখি , তাহলেও এই একই কাজ করবে , প্যারেন্টস ক্লাসের মেথোড কল করবে ।।চলো , কোড দেখে আসি ---------

using System;

public class Employee
{
    public string FirstName="Naim";
    public string LastName="Shahriar";
   
   
    public virtual void printFullName()
    {
       
        Console.WriteLine(FirstName + " " + LastName);
    }
}
public class PartTimeEmployee:Employee
{
    public override void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName + " PartTime");
    }
}
public class FulltimeEmployee:Employee
{
    public override void printFullName()
    {

        Console.WriteLine(FirstName + " " + LastName+" FullTime");
    }
}
public class TemporaryEmployee : Employee
{
   
}

    class Program
    {
        static void Main()

        {
            Employee[] employees = new Employee[3];
            employees[0] = new FulltimeEmployee();
            employees[1] = new PartTimeEmployee();
            employees[2] = new TemporaryEmployee();
            for (int i = 0; i < 3;i++ )
            {
                employees[i].printFullName();
            }
                Console.ReadKey();
        }
    }

তো আশা করি , আর কোনো কনফিউশন থাকলো না । তো আজকে তাহলে এইটুকুই ----------------











No comments:

Post a Comment