Tuesday, July 10, 2018

মহাবিশ্ব ও আমরা - ১ঃ পৃথিবী থেকে শুন্যে


ইন্টারমিডিয়েটে আমরা আপেক্ষিকতা নীতি নিয়ে খুব ছোট একটা লেখা পড়েছি পদার্থবিজ্ঞানে! যেটা পুরোপুরি মাথা খারাপ করে দেওয়ার মত! যেখানে সাধারন পদার্থবিজ্ঞানে বস্তুর ভরকে ধ্রুবক ধরা হয় সেখানে বলা হয়েছে বস্তুর ভরও পরিবর্তনশীল। আইনস্টাইন জীবনের শেষ পর্যায়ে এসে অদ্ভুত এক নীতি আবিষ্কার করে গেছেন। যার মুল বিষয়বস্তু হল মহাবিশ্বের কোন বস্তু পরম নয় সবই আপেক্ষিক।

একটু বুঝিয়ে বলি, মনে করুন আপনি গাড়িতে ভ্রমন করেতেছেন যা ৫০কিমি/সেকেন্ডে সুষম বেগে চলছে। কিন্তু কিভাবে বুঝলেন গাড়িটি চলছে বা এত কিমি বেগে চলছে? স্থির কোন গাড়ি গাছপালার দিকে তাকালেই বুঝা যায় গাড়িটি আসলে চলছে তাইনা? তাছাড়া কোন যন্ত্র ছাড়া বোঝা সম্ভব? সেই স্থির গাড়িটি যদি ৫০ কিমি বেগে বিপরীত দিকে যাত্রা করে তাহলে আপনার গাড়িটির গতিবেগ কত মনে হবে? নিশ্চিৎ ১০০। আবার সেই গাড়িটি যদি ৫০ কিমি বেগে যদি একই দিকে যাত্রা করে তাহলে আপনার গাড়ির গতি কত মনে হবে? নিশ্চিৎ শূন্য! বিশ্বাস না হলে আজই পরীক্ষা করে দেখুন! অথ্যাৎ, ভিবিন্ন প্রসঙ্গ কাঠামোর সাপেক্ষে বস্তুর স্পিড ভিবিন্ন রকম হচ্ছে! অদ্ভুত না?

গাড়ির গতির সাথে সাথেই আমাদের শরীররও সমান গতিপ্রাপ্ত হয়। যে কারনে গাড়ি হঠাৎ ব্রেক কষলে আমরা পেছনের দিকে চলে যাই। এটার প্রমাণ পাওয়া যাবে যদি কোন চলন্ত গাড়ির ছাদে বসে উপরের দিকে কোন বস্তুকে নিক্ষেপ করা হয় তা আবার হাতেই ফিরে আসবে। আরেকটু সহজ করে বলি- ৫০ কিমি/সেকেন্ডে বেগে চলা গাড়ি থেকে যদি কোন বস্তু উপরের দিকে নিক্ষেপ করা হয় তাহলে এক সেকেন্ড পরে তা হাতেই ফিরে আসবে। এটা কিভাবে সম্ভব? কারন এক সেকেন্ড পরে গাড়িতো ৫০ কিমি দূরে চলে যাবে যেখানে বস্তুটি আগের অবস্থায় থাকার কথা কারন বস্তুটির সাথে গাড়ি কিম্বা হাতের কোন স্পর্শ ছিলনা। এটার কারন হল আমাদের হাত গাড়ির সাথে সমান গতিপ্রাপ্ত একই সাথে সেই বস্তুটাও! যে কারনে বস্তুটি হাওয়ায় ঐ ৫০ কিমি অতিক্রম করে আমাদের হাতেই ফিরে আসবে। শরীরের গতিবেগের সাথে মানসিক তারতম্যের কারনেই অনেকে গাড়িতে বমি বমি অনুভব করেন বা বমি করেন। এসবই আপেক্ষিকতার কারন।

কখনো নিজেকে প্রশ্ন করেছেন কেন কোন বস্তুকে দূর থেকে অপেক্ষাকৃত ছোট মনে হয়? ভূমি থেকে সব বস্তুকে এত ছোট দেখায় কেন? মানুষগুলো পিপড়া সাইজের দেখা যায় কেন? এটাও যে একধরনের রিলেটিভিটি তা বললেও ভূল কিছু হবেনা। যাইহোক আমরা সেই বিতর্কে না যাই। যদিও এটার মুল কারন হল বস্তুর সাথে পর্যবেক্ষকের কৌনিক ব্যবধান-
কৌনিক পার্থক্যের কারনে আমরা দূর থেকে কোন জিনিসকে ছোট দেখি
এখন কথা হল ১৩ তলা বিল্ডিং এর ছাদ থেকে মানুষগুলো সহ সবকিছুকে এত এত ক্ষুদ্র মনে হয় সেই সাথে আমরা অনেকগুলো বস্তুকে একসাথে দেখতে পাচ্ছি তাইনা? ঢাকা শহরের কোন ১৩ তলা বিল্ডিং এর ছাদ থেকে মোটামুটি পুরো ঢাকা শহরকে দেখতে পাওয়া যাবে এবং সেই সাথে মানুষগুলো সহ সমস্ত কিছু অপেক্ষাকৃত ক্ষুদ্র মনে হবে।
ড্রোন থেকে আমাদের ঢাকা শহর

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

ট্রপোস্ফিয়ারঃ ০ থেকে ১২ কিলোমিটার (০ থেকে ৭ মাইল)
স্ট্র্যাটোস্ফিয়ারঃ ১২ থেকে ৫০ কিলোমিটার (৭ থেকে ৩১ মাইল)
মেসোস্ফিয়ারঃ ৫০ থেকে ৮০ কিলোমিটার (৩১ থেকে ৫০ মাইল)
থার্মোস্ফিয়ারঃ ৮০ থেকে ৭০০ কিলোমিটার (৫০ থেকে ৪৪০ মাইল)
থার্মোস্ফিয়ারঃ >৭০০
এক্সোস্ফিয়ারঃ <৭০০ কিলোমিটার

এভাবে উপরে উঠতে উঠতে একটা পর্যায়ে নীচের দিকে তাকালে সবুজ গোলাকার পানির ট্যাঙ্কের মত কিছু একটা দেখতে পাবেন। এটাই আসলে আমাদের পৃথিবী। এখানেই আমরা থাকি। এরকম দেখার কারন হল আমরা এতটাই উপরে উঠে গেছি যে পৃথিবী ও চোখের কৌনিক ব্যাবধান এতটাই ক্ষুদ্র হয়েছে যে দেশ, মহাদেশ ছাড়িয়ে আমরা পুরো পৃথিবীকে এক দৃষ্টিতে দেখতে পাচ্ছি। যেমনটা বাসার ছাঁদে উঠলে পুরো ঢাকা শহরকে দেখা যায়।

মোটামুটি ভূপৃষ্ট থেকে ১০০০ কিলোমিটার উপরে উঠে যাওয়ার পর আমরা স্বাভাবিকভাবে আর পৃথিবীতে ফেরত আসবোনা। এখানে আমরা ভাসতে থাকবো। এই অঞ্চলকেই বলা হয় মহাকাশ। এই অঞ্চলের কোন শেষ নেই। এই মহাকাশের বিস্তার কতটূকু তা আজ পর্যন্ত মানুষের দ্বারা বের করা সম্ভব হয়নি।

ছবিটি ইন্টারন্যাশনাল স্পেস স্টেশন থেকে তোলা 

আমরা সবাই জানি মহাকাশে ইন্টারন্যাশনাল স্পেস স্টেশন নামে একটা কৃত্রিম উপগ্রহ আছে। মহাকাশ নিয়ে গবেষনার জন্য ১৯৯৮ সালে এটি চালু করা হয়। পৃথিবীর প্রায় ১৬ টি দেশ নিয়ে গঠিত এই কৃত্রিম উপগ্রহটি পৃথিবী থেকে ৪০৮ কিলোমিটার দূরে অবস্থিত।  জিরো গ্র্যাভিটিতে বা ভাসমান অবস্থায় মানুষ এখানে কিভাবে থাকে তা সম্পর্কে স্পষ্ট ধারনা পাওয়া যাবে এই ভিডিওতে-



পরবর্তীতে মহাকাশ সম্পর্কিত আরো দারুন কিছু বিষয় নিয়ে কথা হবে।

Thursday, June 28, 2018

ডাটা স্ট্রাকচার - ২ঃ অ্যারের ভিতর বাহির


যদি তোমাকে বলা হয় ৫০ টা নাম্বার একত্রে যোগ করে দাও তাহলে তুমি কি করবে? তুমি কি আগের মত ৫০ টা ভেরিয়েবল ডিক্লেয়ার করে তারপর ইনপুট নিবে? কখনোই না। কারন এটা সময় সাপেক্ষ!

তাহলে আমাদের এমন একটা অবস্থা থাকা দরকার যা দ্বারা আমরা খুব দ্রুত অনেকগুলো ভেরিয়েবল ডিক্লেয়ার করে ফেলতে পারবো! হ্যাঁ, একটা ফিচার আছে যার নাম অ্যারে।  অ্যারে ডিক্লেয়ার করার নিয়মটা হল-  Data_Type variable_name[size]; নীচের উদাহরনটা দেখো-

int value[50];
এটা দেওয়ার সাথে সাথেই কিন্তু ৫০ টা ভেরিয়েবল ডিক্লেয়ার হয়ে গেছে। এই ভেরিয়েবলগুলো হল-
value[0],value[1],value[2],value[3],value[4],value[5],value[6],value[7],value[8],value[9].........value[49]
ব্র্যাকেটের ভেতরের সাইজ পরিবর্তন করে এভাবে আমরা যেকোন পরিমান ভেরিয়েবল তৈরী করে ফেলতে পারি। লুপ চালিয়ে খুব সহজভাবেই আমরা এর ভেতরে ডাটা রাখতে পারি এবং ডাটা দেখতে পারি।  নীচের প্রোগ্রামটি খেয়াল করো-

Program - 1: Input 5 numbers in an array and sum it

 #include <stdio.h>  
 int main()  
 {  
   int num[5], i, sum = 0;  
   for(i = 0; i<5; i++)  
   {  
     scanf("%d", &num[i]);  
   }  
   for(i = 0; i<5; i++)  
   {  
     sum+= num[i];  
   }  
   printf("Sum: %d\n", sum);  
   return 0;  
 }  

 Input:   
 10 20 30 40 50   
 Output  
 150  

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

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

Program - 1: Print the Memory of an array and normal variables 

 #include <stdio.h>  
 int main()  
 {  
   int i, num[10], sum = 0;  
   printf("Memory Address of array: ");  
   for(i = 0; i<10; i++)  
   {  
     printf("%d ", &num[i]);  
   }  
   printf("\n");  
   printf("Memory address of variables: ");  
   printf("%d %d\n", &i, &sum);  
   return 0;  
 }  

 Output:   
 Memory Address of array: 6356708 6356712 6356716 6356720 6356724 6356728 6356732 6356736 6356742 6356744  
 Memory address of variables: 6356748 6356724  

উপরে দেখা যাচ্ছে অ্যারের মেমরি অ্যাড্রেস একটা সিকুয়েন্স মেন্টেন করে চলছে। প্রতিটা মেমরি অ্যাড্রেসের পার্থক্য ৪ করে। কিন্তু ভেরিয়েবলের ক্ষেত্রে ব্যাপারটা অন্য রকম। আমরা যত ভেরিয়েবলই ডিক্লেয়ার করিনা কেন তা পাশাপাশি থাকবে কি থাকবেনা তার কোন গ্যারান্টি নাই। অথ্যাৎ, তাদের অবস্থান বা সিকুয়েন্স এর উপর আমাদের কোন নিয়ন্ত্রন নাই। যেটা অ্যারের ক্ষেত্রে পাওয়া যায়। অ্যারের সাইজ যতই হোক না কেন এটা যে নিশ্চিৎ যে সবগুলো ভেরিয়েবল পাশাপাশি অবস্থান করবে। এই অ্যারেটা যদি আমরা ভিজুলাইজ করি তাহলে এমন দেখাবে-
অ্যারের আরেকটা মজার বৈশিষ্ট্য হল অ্যারের নামটা পয়েন্টার হিসেবে কাজ করে এবং সেই পয়েন্টারে প্রথম ভেরিয়েবলটার অ্যাড্রেস থাকে। সেই অনুযায়ী উপরে num হল একটি পয়েন্টার এবং এর কছে num[0] এর অ্যাড্রেস থাকে। বিশ্বাস না হলে num[0] এর মেমরি অ্যাড্রেস এবং পয়েন্টারটা প্রিন্ট করে দেখো। 

অ্যারের এই বৈশিষ্ট্যটা কাজে লাগিয়ে আমরা ইন্ডেক্সিং এবং & ছাড়াই ডাটা ইনপুট এবং আউটপুট দেখাতে পারি। নীচের প্রোগ্রামটি খেয়াল করো- 

Program - 3: Input 10 numbers in an array and print it. Don't use any ampersand or array indexing 

 #include <stdio.h>  
 int main()  
 {  
   int i, num[10], sum = 0;  
   int *ptr = num;  
   for(i = 0; i<10; i++)  
   {  
     scanf("%d", ptr);  
     ptr++;  
   }  
   ptr = num;  
   for(i = 0; i<10; i++)  
   {  
     printf("%d ", *ptr);  
     ptr++;  
   }  
   return 0;  
 }  

 INPUT   
 10 20 30 40 50 60 70 80 90 100  
 OUTPUT  
 10 20 30 40 50 60 70 80 90 100  

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

এখানে num হল সেই গনু মোল্লা এবং ptr  হল সেই ট্রাম্প সাহেব। ট্রাম্প সাহেব তোমার এলাকায় আসার সাথে সাথেই গনু মোল্লা ptr = num দিয়ে জানিয়ে দিলো তোমার বাসার অ্যাড্রেস। তারপর কি হল সেটা তো তুমিই জানো।

একদম শুরুতে num এবং ptr প্রথম অবস্থানে থাকে এবং  ptr প্রতিবার এক এক করে  বাড়াতে বাড়াতে সবগুলো অ্যাড্রেসে যেতে পারছে এবং সেই পার্টিকুলার অ্যাড্রেসের ডাটা নিতে বা রাখতে পারছে। একে পয়েন্টিং বলা হয় আর ptr বা num কে পয়েন্টার বলা হয়। এভাবে একটা লিস্ট বা অ্যারের শেষ পর্যন্ত সে ট্রাভেল করতে পারে। এভাবেই অ্যারে কাজ করে। আশাকরি বুঝতে সমস্যা হয়নাই।

প্র্যাক্টিস প্রব্লেমঃ
১। ট্রাম্প যদি গনু মোল্লাকে নিয়েই সবগুলো বাড়িতে যেতেন তাহলে কি সমস্যা হতো, উত্তর জানাও কমেন্টে।

Wednesday, March 28, 2018

অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং - ৭ঃ ইন্টারফেস

ইন্টারফেস অনেকটা অ্যাবস্ট্র্যাক্ট ক্লাসের মতই তবে এর ভেতরে কোন কনক্রেট মেথড থাকেনা। মানে হল সবগুলো মেথডই এখানে অ্যাবস্ট্র্যাক্ট। ইন্টারফেস মানেই যেহেতু অ্যাবস্ট্র্যাক্ট সেহেতু এর ভেতরে কোন মেথডকে অ্যাবস্ট্র্যাক্ট লিখে দেওয়ার দরকার পড়েনা। আমরা সেই Animal উদাহরনে ফিরে যাই-

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

 public interface Animal {  
      public void Walk();  
      public void Speak();  
 }  
 public class Human implements Animal {  
      public void Walk()  
      {  
           System.out.println("Human walk using two legs");  
      }  
      public void Speak() {  
           System.out.println("Human can speak using- Hi, Hello");  
      }  
 }  
 public class Dog implements Animal {  
      public void Walk() {  
           System.out.println("Dog walk using two legs");  
      }  
      public void Speak() {  
           System.out.println("Dog can speak something like Woof");  
      }  
 }  
 public class StartUp {  
      public static void main(String[] args) {  
           Human human1 = new Human();  
           human1.Walk();  
           human1.Speak();  
           Dog dog1 = new Dog();  
           dog1.Walk();  
           dog1.Speak();  
      }  
 }       
 OUTPUT  
 Human walk using two legs  
 Human can speak using- Hi, Hello  
 Dog walk using two legs  
 Dog can speak something like Woof  

ইন্টারফেস কেন দরকারঃ
১। টিমওয়ার্কে সকল টিম মেম্বারদের একটা নিয়মের মধ্যে রাখাঃ মনে করো তুমি একজন প্রোজেক্ট লিডার। তুমি একটি প্রোজেক্ট করতে যাচ্ছো যেখানে অনেক গুলো ক্লাস লিখতে হবে। একেকটা ক্লাসের দায়িত্ব একেকজন মেম্বারকে দিয়ে দিয়েছো।  তুমি চাচ্ছো সবগুলো ক্লাসে এমন কিছু জিনিস থাকতেই হবে। তুমি সিমপ্লি একটা ইন্টারফেস লিখে দিলে এবং সবাইকে বলে দিবে সবাই যেন ঐ ইন্টারফেসটা Implement করে। এখন সেই ইন্টারফেসটা ইমপ্লিমেন্ট করতে গেলে তাকে অবশ্যই সেই জিনিসগুলো ইমপ্লিমেন্ট করতে হবে যা তুমি ইন্টারফেসের ভিতর লিখে দিয়েছো :D
এতে তিনটা লাভ হল- সবাই ঐ মেথডগুলো লিখতে হবে, মেথডগুলোর নাম একই ইউজ করবে। কেউ রাম, কেউ সাম কেউ যদুমদু লিখার সুযোগ পাবেনা :D

২। মাল্টিফল ইনহেরিটেন্সঃ জাভাতে মাল্টিফল ইনহেরিটেন্স সাপোর্ট করেনা। কিন্তু ইন্টারফেস ইউজ করে তুমি একাধিক interface ইমপ্লিমেন্ট করতে পারবে।

৩। মেথডের বডি নিয়ে কনফিউশনঃ তুমি জানো এই প্রোজেক্টে এই মেথডটা থাকা উচিৎ কিন্তু শিওর না কোন ক্লাসের জন্য বডি কি রকম হবে বা এক্সট্রা কি লাগতে পারে। সেক্ষেত্রে এটা আনইমপ্লিমেন্টেড রেখে দেওয়া যায় পরে যার ক্লাসের জন্য যেরকম দরকার হবে সে ওরকম বডি লিখে নিতে পারবে। 

Tuesday, March 27, 2018

অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং - ৬ঃ অ্যাবস্ট্রেকশন


যে মেথডের কোন বডি থাকেনা সেটাই হল অ্যাবস্ট্রেক্ট মেথড। আর যে ক্লাসে অ্যাবস্ট্রেক্ট মেথড থাকে সেই ক্লাসই অ্যাবস্ট্রেক্ট ক্লাস।  অ্যাবস্ট্রেক্ট মেথড দেখতে ঠিক এরকম-

 public abstract void exampleOfAbstracMethod();  

তো কথা হল যে মেথডের বডিই নাই সেই মেথডের লেখারই কি দরকার? আমাদের সেই বিখ্যাত Animal এবং Human ক্লাসের উদাহরনটায় ফেরত যাই। Animal ক্লাসে লিখেছিলাম Animal রা হাটতে পারে কিন্তু বিষয়টা ক্লিয়ার না। কারন পৃথিবীতে হাজার হাজার প্রাণী আছে সব প্রানীর হাটা ধরন এক না বা সবার পায়ের সংখ্যা সমান না। তার মানে হল এই মেথডটার বডিতে কি লিখতে হবে আমরা নিশ্চিৎ না। যে কারনে আগের পর্বে আমরা একে ওভাররাইড করে ফেলছিলাম। যেহেতু একটা মেথডের বডি সম্পর্কে আমরা নিশ্চিৎ না সেহেতু তার বডি লিখে সময় নষ্ট করার দরকার আছে? বেটার আমরা ঐ মেথডটার বডি Unimplemented রেখে দিবো।  কোন মেথড আন ইমপ্লিমেন্টেড করতে হলে তার আগে Abstract লিখতে হয়। আর কোন ক্লাসে যদি অন্তত একটা অ্যাবস্ট্রেক্ট মেথড থাকে তাহলে সেই ক্লাসকেও অ্যাবস্ট্রেক্ট করতে হয়। তো আমরা আগের উদাহরনটা এখানে ইমপ্লিমেন্ট করি-

 public abstract class Animal {  
      public abstract void Walk();  
      public void Call()  
      {  
           System.out.println(" Can call");  
      }       
 }  
 public class Human extends Animal {  
      public void Walk()  
      {  
           System.out.println("Human walk using two legs");  
      }  
 }  
 public class MainClass{  
      public static void main(String[] args) {  
           Human human1 = new Human();  
           human1.Walk();  
      }  
 }  
 OUTPUT  
 Human walk using two legs  


কিছু বিষয়- 
১। অ্যাবস্ট্র্যাক্ট ক্লাসের কোন অবজেক্ট তৈরী করা যায়না কারন অ্যাবস্ট্র্যাক্ট ক্লাসের আন ইমপ্লিমেন্টেড মেথড থাকে
২। যখন কোন ক্লাসে নির্দিষ্ট একটা মেথড অবশ্যই থাকা উচিৎ বলে মনে করা হয় কিন্তু ভেতরে কি লিখতে হবে তা নিশ্চিৎ শুধু সে ক্ষেত্রেই অ্যাবস্ট্রেক্টেড মেথড ইউজ করা হয়।
৩। অ্যাবস্ট্রেক্ট ক্লাসকে যারা ইনহেরিট করবে তাদেরকে অবশ্যই অ্যাবস্ট্র্যাক্ট মেথড ইমপ্লিমেন্ট করতে হবে। নাহলে কম্পাইলার এরর দিবে। যদি না করা হয় তাহলে ইনহেরিটেড ক্লাসকেও অ্যাবস্ট্রেক্ট করে দিতে হবে। মানে আজ হোক কাল হোক অবজেক্ট তৈরী করতে হলে ইমপ্লিমেন্ট করা লাগবেই :P
৪। অ্যাবস্ট্র্যাক্ট ক্লাসে একই সাথে অ্যাবস্ট্রেক্ট মেথড এবং কনক্রেট মেথড( ইমপ্লিমেন্টেড) থাকতে পারে।

অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং - ৫ঃ পলিমরফিজম

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

ওভারলোডিংঃ ওভারলোডিং হল একই মেথড নেম কিন্তু ভিন্ন ভিন্ন প্যারামিটার। মাঝে মাঝে প্রোগ্রামিং করার সময় আমাদের এমন অবস্থা তৈরী হয় যে, কয়েকটা মেথডের ভিন্ন ভিন্ন প্যারামিটার দরকার হয় কিন্তু একই কাজ করে। সেক্ষেত্রে একই নাম ব্যবহার করা সবচেয়ে ভালো প্র্যাক্টিস। আর সেজন্যই ওভারলোডিং জিনিসটা রাখা হয়েছে OOP তে।

যেমন ধরো,আমাদের যোগ করা দরকার। আমার কখনো ২ নাম্বার যোগ করার দরকার পড়ে, কখনো ৩ টা আবার কখনো ৪ টা। এই কাজটি আমরা মেথড দিয়ে করতে চাই।  আমরা জানি মানুষ চিন্তা করতে পারে।  তার মানে মানুষ যোগ করতে পারে। তাহলে আগের পর্বের মানুষের যে Think() নামক মেথডটা লিখছিলাম সেটা দিয়েই কাজটা সারতে পারি। দেখো কাজটা আমরা কিভাবে করি :P
 public class Human extends Animal {  
      double sum;  
      public void think()  
      {    
           System.out.println("Wanna see that I can think?")
           System.out.println("Give me some number and see I can do sum");  
      }  
      public void think(double a , double b)  
      {  
           sum = a+b;  
           System.out.println(sum);  
      }  
      public void think(double a , double b, double c)  
      {  
           sum = a+b+c;  
           System.out.println(sum);  
      }  
      public void think(double a , double b, double c, double d)  
      {  
           sum = a+b+c+d;  
           System.out.println(sum);  
      }  
 }  
 public class StartUp {  
      public static void main(String[] args) {  
           Human human1 = new Human();  
           human1.think();  
           human1.think(30,40);  
           human1.think(30,40,50);  
           human1.think(50,60,70,80);  
      }  
 }  
সবগুলো মেথডের নামই সেইম। তবে তাদের আলাদা আলাদা প্যারামিটার। কোন মেথডটা কল হবে তা নির্ভর করে ৩ টা জিনিসের উপর-
১। মোট প্যারামিটার সংখ্যা ।
২। প্যারামিটারের ডাটা টাইপ।
৩। ডাটা টাইপের সিকুয়েন্স।
এই তিনটা জিনিস যে মেথডের সাথে মিলবে সেই মেথডটাই কল হবে।

 OUTPUT
 Wanna see that, I can calculate?  
 Give some number and see I can add  
 70.0  
 120.0  
 260.0  

উপরে আমি যদি মেইন ফাংশ থেকে জিরো প্যারামিটার কল করি তাহলে প্রথম মেথডটা কল হবে, আবার ৪ টা ডাবল টাইপ প্যারামিটার দিয়ে কল করি তাহলে শেষেরটা কল হবে। তবে অন্য কোন ডাটা টাইপ দিয়ে কল করলে কোনটাই কল হবেনা। আশা করি বুঝতে সমস্যা হচ্ছেনা।

ওভাররাইডিংঃ 


উপরে দেখা যাচ্ছে, Animal ক্লাসকে Human এবং Dog ক্লাস Inherit করেছে।  Animal ক্লাসের ভিতর Walk এবং Call মেথড লিখা আছে। কিন্তু একটা সময় পর তোমার মনে হল Animal ক্লাসের মেথডটি Human বা Dog ক্লাসের জন্য পর্যাপ্ত না অথবা সাবক্লাস দুটোতে সেটার সংশোধন করা দরকার সেক্ষেত্রে তুমি সেই মেথডটাই সাবক্লাসে লিখে দিবে। তখন সাবক্লাসের জন্য Animal ক্লাসের মেথডটা আর কাজ করবেনা; যেটা সাবক্লাসে লিখে দিয়েছো সেটাই কাজ করবে। মানে হল প্যারেন্ট ক্লাসের একটা মেথড সাবক্লাস দিয়ে ওভাররাইড হয়ে গেছে। আবার তুমি যদি মেইন ক্লাসের অবজেক্ট দিয়ে কল তাহলে আবার মেইন ক্লাসেরটাই কাজ করবে।  যেহেতু কোন মেথডটা কখন কল হয় তা রানটাইমে নির্ধারন হয় সেহেতু একে রানটাইম পলিমরফিজম বা ডায়নামিক পলিমফিজম বলা হয়।

 public class Animal {  
      public String name;  
      public int age;  
      public void Walk()  
      {     
           System.out.println("This message is from base class: ")
           System.out.println("Can Walk");  
      }  
      public void Call()  
      {  
           System.out.println(" Can call");  
      }       
 }  
 public class Human extends Animal {  
      public void Walk()  
      {  
           System.out.println("This message is from sub class:");  
           System.out.println("Human walks using two legs");  
      }  
 }  
 public class MainClass{  
      public static void main(String[] args) {  
           Human human1 = new Human();  
           human1.Walk();  //Walk() will be called on Human class. 
          
          Animal animal1 = new Animal();
          animal1.Walk();  //Walk will be called on Animal class 
      }  
 }  
 OUTPUT  
 This message is from sub class:  
 Human walks using two legs  

This message is from base class:
Can Walk


অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং - ৪ঃ ইনহেরিটেন্স

ইনহেরিট হল একটা ক্লাসের এলিমেন্ট অন্য ক্লাসে নিয়ে আসা। এটা পুরোটা রিয়েল লাইফ ইনহেরিটেন্স এর মত। কেউ যদি উত্তরাধিকার সূত্রে কোন কিছুর মালিক হয় তাকেই ইনহেরিটেন্স বলে। অব্জেক্ট অরিয়েন্টেডেও বিষয়টা এরকমই। কিন্তু এটা কেন দরকার-
ধরা যাক, আমরা দুটো ক্লাস তৈরী করবো, Human এবং Dog নামে। ক্লাসগুলোতে কি কি থাকবে তা নীচের টেবিলে দেওয়া হল-

এই দুটো ক্লাস লিখতে হলে আমাদের মোট ৪ টা ভেরিয়েবল এবং ৫ টা মেথড লিখতে হবে। কিন্তু যদি একইভাবে আমাদের ১০০০ টা প্রাণী নিয়ে লিখতে হয় তাহলে আমাদের টোটাল ভেরিয়েবল এবং মেথডের সংখ্যা কত হবে জানো? টোটাল ভেরিয়েবল হবে ৪০০০০ এবং টোটাল মেথড হবে ৫০০০। জীবন শেষ! আর ক্লাসের ভিতর আরো বেশী কিছু লিখার দরকার হবে তাতে তো কোন কথাই নাই। কোডিং না করে পালানো লাগবে! তবে আমরা চাইলে এই সংখ্যাটা অনেক কমিয়ে আনতে পারি।

উপরে টেবিলের দিকে খেয়াল করো আমরা কয়েকটা জিনিস একাধিকবার লিখছি। অবজেক্ট অরিয়েন্টেডের একটা নিতী হল কোডের রিপিটেশন কমানো কিন্তু আমরা সেই কাজটিই করে বসেছি। নীচের ছবিতে দেখো -


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


আমরা জানি সকল প্রানীরই name এবং age থাকে। আবার প্রানীই হাটতে এবং ডাকতে পারে। তাই ওই ক্লাসের নাম দিলাম Animal. তুমি চাইলে যেকোন মিনিংফুল নাম দিতে পারো। 
উপরে দেখা যাচ্ছে Human এবং Dog ক্লাস Animal ক্লাসকে Inherit করছেএর ফলে Animal ক্লাসে যা আছে তা Human এবং Dog ক্লাসে চলে আসছে। তাহলে আমাদের আর রিপিট এলিমেন্ট গুলো আর লিখতে হচ্ছেনা। এখানে আমরা ৯ টা এলিমেন্ট এর পরিবর্তে ৬ টা লিখে কাজ সেরে ফেলছি। ১০০০ এর জন্য এখন কয়টা লিখতে হচ্ছে জানো ?  ২ টা ভেরিয়েবল এবং ৩টা মেথড!! এভাবে আমরা কোড রিপিটেশন থেকে মুক্তি পেতে পারি এবং অনেক অনেক সময় বেঁচে যায়।
একটা ক্লাসকে ইনহেরিট করার জন্য জাভাতে extends নামের দারুন এক অপারেটর আছে। যা দিয়ে একটা ক্লাসকে অন্য ক্লাস থেকে ইনহেরিট করা যায়। আমরা উপরের কাজটিই জাভা দিয়ে লিখবো-
 public class Animal {  
      public String name;  
      public int age;  
      public void Walk()  
      {  
           System.out.println(name+ " Can walk");  
      }  
      public void Call()  
      {  
           System.out.println(name+ " Can Call");  
      }       
 }  
 public class Human extends Animal {  
      public void think()  
      {  
           System.out.println(name+ "Can think");  
      }  
 }  
 public class Dog extends Animal {  
 }  
 public class MainClass{  
      public static void main(String[] args) {  
            
           //creating humans object
           Human human1 = new Human();  
           human1.name = "Rakib";  
           human1.age = 23;  
           
           //creating dogs object
           Dog dog1 = new Dog();  
           dog1.name = "John";  
           dog1.age = 2;  
          
           //showing humans information
           System.out.println(human1.name+ " is "+ human1.age+ " Years Old");  
           human1.Walk();  
           
           //showing dogs information
           System.out.println(dog1.name+ " is "+ dog1.age+ " Years Old");
           dog1.Walk();  
      }  
 }  
 OUTPUT  
 Rakib is 23 Years Old  
 John is 2 Years Old  
 Rakib Can Walk  
 John Can Walk  
Extends - এটা হল জাভার একটি অপারেটর, যার সাহায্যে এক ক্লাসের পাবলিক এলিমেন্ট অন্য ক্লাসে ইনহেরিট করানো হয়।
Practice:
1. Do the above task using encaptulation and constructor

অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং - ৩ঃ কনস্ট্রাক্টর



কোন কিছু Initilize করার জন্য বার বার setName, setAge কল করতে হচ্ছে। এরকম যদি ১০০ টা ভেরিয়েবল ইনিসিয়ালিজ করার দরকার পড়ে তাহলে কি তুমি বার বার set মেথড লিখবা? কখনোই না বরং এটা অনেক সময় সাপেক্ষও বটে! সেক্ষেত্রে আমাদের এমন কিছু একটার প্রয়োজন যেটায় অব্জেক্ট ক্রিয়েট করার সাথে সাথেই এগুলো বা মেন্ডেটরি জিনিসগুলো Initilize করে দিবে। সেজন্য আমরা Human ক্লাসের ভেতরেই একটা কনস্ট্রাক্টর লিখে দিবো-

কনস্ট্রাক্টরের বৈশিষ্ট্যঃ কনস্ট্রাক্টর অনেকটা ফাংশনের মত। তবে এর কোন রিটার্ন টাইপ থাকেনা এবং এর নাম ঐ ক্লাসের নাম অনুযায়ী হয়ে থাকে। নীচের প্রোগ্রামটি লক্ষ্য করিঃ

 public class Human {  
      private String name;  
      private int age;  
      public Human(String Name, int Age)  
      {  
           name = Name;  
           age = Age;  
      }  
 }  

মেইন ফাংশন থেকে এখন এইটুকু করে দিলেই কাজ শেষ-
 public class StartUp {  
      public static void main(String[] args) {  
           Human aHuman = new Human("Rakib", 23);  //creating object  
      }  
 }  

কনস্ট্রাক্টরের কাজই হল  প্রয়োজনীয় মেমরি তৈরী করে অব্জেক্টে পাঠিয়ে দেওয়া এবং ভেরিয়েবলগুলো ইনিসিয়ালাইজ করা। যদি প্রোগ্রামার কোন কনস্ট্রাক্টর না লিখে তাহলে সিস্টেম ডিফল্ট কন্সট্রাক্টর কল করে।

ডিফল্ট কন্সট্রাক্টরঃ আমরা যদি কোন কনস্ট্রাক্টর তৈরী না করি তাহলে সিস্টেম ডিফল কন্সট্রাক্টর ইউজ করে। ডিফল্ট কন্সট্রাক্টর হচ্ছে এরকম-

 public Human()  
      {  
      }  

new অপারেটরঃ এটা একটি জাভা অপারেটর। এই অপারেটরের সাহায্যেই কন্সট্রাক্টর অব্জেক্ট তৈরী করে। এটা দ্বারা কম্পাইলারকে বুঝানো হয় যে আমরা নতুন একটি অব্জকেট ক্রিয়েট করতে চাচ্ছি। 

Monday, March 19, 2018

অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং - ২ঃ ইনক্যাপসুলেশন


ধরা যাক, তোমাকে বলা হল নতুন করে Human নামের একটা ক্লাস তৈরি করো যে ক্লাসটি শুধু নাম এবং বয়স রাখতে পারে। ক্লাসটি লিখে ফেলি-

//File: Human.java
 public class Human {  
      public String name;  
      public int age;  
 }  
যেহেতু name এবং age পাবলিক, সেহেতু যেকোন ক্লাস থেকে এদেরকে Initilize করা যাবে। এখন আমরা মেইন ক্লাস থেকে একই সাথে Initilize এবং প্রিন্ট করে ফেলবো।

 //file: StartUp.java 
public class StartUp {  
      public static void main(String[] args) {  
           Human aHuman = new Human();  //creating object  
           aHuman.name = "Rakib";    //Initialize name   
           aHuman.age = 25;       //Initialize age  
           System.out.println(aHuman.name); //print name  
           System.out.println(aHuman.age); //print age  
      }  
 }  

Output
Rakib 25

কিন্তু Human ক্লাস ডিজাইনে একটু সমস্যা আছে। যেহেতু ক্লাসের ডাটা বা ভেরিয়েবলগুলো অন্য ক্লাস থেকে অ্যাক্সেস করা যায় সেহেতু চাইলেই যেকোন ভেলু যেকোন ক্লাস থেকে অ্যাসাইন করা যায়। যেমন ধরো তুমি বা অন্য কোন ইউজার চাইলেই aHuman.name = "Dog" বসিয়ে দিতে পারো অথবা aHuman.age = -40 বসিয়ে দিতে পারো যেটা অপ্রত্যাশিত! কারন বয়স কখনো নেগেটিভ হতে পারেনা।  অথ্যাৎ, ভেরিয়েবলগুলোর আমার নিয়ন্ত্রন থাকছেনা। সেক্ষেত্রে আমরা এই ফিল্ডগুলোকে প্রাইভেট করে দিলেই ঝামেলা শেষ। কিন্তু এতে আরেকটা ঝামেলা আছে। আমরা কোন ভেলিড ভেলুও বসাতে পারবোনা বাইরে থেকে। আর এই অ্যাসাইনমেন্টের কাজ টা মেথডের মাধ্যমে করবো। যেখানে কন্ডিশন দেওয়া থাকবে কোন কোন পরিস্থিতিতে আমরা ভেলু অ্যাসাইন বা সেট করবো।

আমরা Human ক্লাসের name এবং age সেট করার জন্য দুইটা পাবলিক মেথড লিখতে পারি। যদি ডাটাগুলো ঠিকঠাক দেওয়া হয় তাহলেই আমরা assign করতে দিবো নাহলে দিবোনা। আর name এবং age কে যেন বাইরে থেকে সরাসরি সেট করা না যায় তাই এই দুটোকে private করে দিবো। মানে হল ডাটা অ্যাসাইন করতে হলে মেথডের মধ্য দিয়েই করতে হবে সরাসরি করা যাবেনা। এতে ফিল্ড সেট করার ক্ষেত্রে আমাদের নিয়ন্ত্রন থাকে কারন মেথডের ভিতরে আমরা ইচ্ছেমত কন্ডিশন সেট করতে পারি।
তো, Human ক্লাসটা আপডেট করে ফেলি। বিষয়টা অনেকটা এরকম-

এটাই কোডে ইমপ্লিমেন্ট করে দেখি-
 public class Human {  
      private String name;  
      private int age;  
      public void setName(String Name) {  
           name = Name;  
      }  
      public void setAge(int Age)  
      {  
           if(Age>0)  
                age = Age;  
           else  
                System.out.println("Please input valid age");  
      }  
 }  

এখন চাইলেও আগের মত ইনভেলিড ডাটা রাখতে পারবেনা। এখানে private ইউজ করার ফলে অন্য ক্লাস থেকে এই ডাটাগুলো আর অ্যাক্সেস করা যাবেনা। শুধু যে ক্লাসে ডিক্লেয়ার করা হয় সেই ক্লাসেই ব্যবহার করা যাবে। এই পদ্ধতিকে বলা হয় ডাটা হাইডিং বা ইনক্যাপসুলেশন। তাই সবসময় ডাটা প্রাইভেট রাখা উচিৎ এবং সেট বা গেট করার জন্য আলাদা পাবলিক ফাংশন ইউজ করাটা বেস্ট প্র্যাক্টিস।

ডাটা অ্যাক্সেস নিয়ন্ত্রনের জন্য জাভাতে তিন ধরনের কিওয়ার্ড আছে। Public, Private এবং Protected. এদেরকে সাধারনত Access Modifier বলা হয়।






প্র্যাক্টিস প্রব্লেমঃ

1. Create a Class named Bank. It can deposit money, withdraw money and show the current balance. Make sure that, the bank class is secure enough.




Friday, March 9, 2018

অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং - ১ঃ কনসেপ্ট


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

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


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

আচ্ছা, তাহলে ক্লাস পাওয়া গেল। কিন্তু অবজেক্ট কোনটা? অবজেক্টই হল, রাকিব এবং জন! তাহলে অবজেক্ট এর সংজ্ঞা কি হতে পারে? অবজেক্ট হল এমন একটা জিনিস যা নির্দিষ্ট একটা ক্লাসের প্রতিনিধি হিসেবে কাজ করে। এখানে জন এবং রাকিব হল যথাক্রমে কুকুর এবং মানুষ শ্রেনীর প্রতিনিধি করে। মানে হল একটা ক্লাসের যে যে বিশিষ্ট থাকে তা অবজেক্টের মধ্যে খুঁজে পাওয়া যায়। যেমনটা আমি রাকিবকে পর্যবেক্ষন করলে মানুষের গুনগুলো খুঁজে পাবো।

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


দেখতেই পারছো একটা ক্লাসের ভিতরে কয়েকটা ভেরিয়েবল এবং ফাংশন। এরকম হাজার হাজার ভেরিয়েবল এবং ফাংশন একটা ক্লাসের ভেতর এঁটে দেওয়া যায়। এটা অনেকটা ফাংশনের এক্সটেন্ডেড ভার্সন বলা চলে।  আবার সেই ক্লাসটাই একটা ভেরিয়েবলের বা অবজেক্ট এর ভিতর নিয়ে আসা যায় । যেমন উপরের উদাহরনে রাকিব এবং জন! উপরের কথাগুলোই এখন জাভা দিয়ে লেখার চেষ্টা করি -
 //file: Human.java  
    class Human{   
    String name, hands, Eyes,legs;   
    int age;  
    void Eat()   
    {   
       System.out.println("Eating");   
    }   
    void Walk()   
    {   
       System.out.println("Walking");   
    }   
    void Think()   
    {   
       System.out.println("Thinking");   
    }   
    void Call()   
    {   
       System.out.println("Hello...");   
    }   
  }   

  //file: Dog.java   
  class Dog{   
    String name, hands, eyes, legs;  
    int age;  
    void Eat()   
    {   
       System.out.println("Eating");   
    }   
    void Walk()   
    {   
       System.out.println("Walking");   
    }   
    void Bark()   
    {   
       System.out.println("Gheu Gheu...");   
    }   
  }   

যা বললাম হুবহু প্রোগ্রামিং তা ই করলাম। এখন মেইন ক্লাস থেকে হিউম্যান এবং ডগ এর অবজেক্ট তৈরী করবো। মনে রেখো, এক ক্লাস থেকে অন্য ক্লাসের এলিমেন্ট ব্যবহার করতে হলে অবজেক্ট তৈরী করতে হয়। সাধারনত অবজেক্ট ছাড়া এটা করা যায়না। একটা ক্লাস থেকে আনলিমিটেড অবজেক্ট তৈরী করা যায় এবং প্রতিটা অবজেক্ট স্বতন্ত্র!

  //File: MainClass.java  
    public class MainClass {   
    public static void main(String[] args) {   
       Human Rakib = new Human(); //Creating Human's object. it's Rakib   
       Rakib.name = "Rakib"  //set the name
       Rakib.age = 23;  //set age 
       Rakib.Think();    //Instruct Rakib to think   
       Dog John = new Dog();  //Creating Dogs's object. It's John    
       John.Bark();    //Instruct John to Bark   
       System.out.println(Rakib.name);  //Print the name
       System.out.println(Rakib.age);  //Print age
  }   
  }   

 Output   
 Thinking   
 Gheu Gheu...  
 Rakib  
 23   

পুরো ব্যাপারটাকে এক দৃষ্টিতে দেখার চেষ্টা করিঃ

ক্লাসঃ এক সেট নির্দিষ্ট গুন/ বৈশিষ্ট্য
অবজেক্টঃ একটি বস্তু বা যেকোন কিছু যা একটি নির্দিষ্ট ক্লাসের বৈশিষ্ট্য বহন করে। অব্জেক্ট তৈরী করার স্ট্রাকচার -
<Class Name>  <A variable/ObjectName>  = <new> <ClassName()> 

মেথডঃ কোন নির্দিষ্ট কাজ সম্পর্ন করাকেই মেথড বা ফাংশন বলে। যেমন,  খাওয়া-দাওয়া, হাটা।
ইনস্ট্যান্স বা ভেরিয়েবলঃ কোন মেথডের কাজ সম্পর্ন করতে যেসব জিনিস ব্যাবহার করা হয় তাদেরকেই ভেরিয়েবল বলে। যেমন, হাত-পা, মুখ।

এতক্ষনে হয়তো বুঝে যাওয়ার কথা অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং কি ! সোজা কথায় যে ধরনের প্রোগ্রামিং ল্যাঙ্গুয়েজ অবজেক্ট নিয়ে কাজ করে তাকেই অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং বলে, ব্যাস! যেমন, সি প্লাস প্লাস, জাভা, সি শার্প, পাইথন ইত্যাদি! আচ্ছা তাহলে অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং কেন করবো? বা তার সুবিধা কি?

 এটার অনেকগুলো সুবিধা আছে সেগুলো হলঃ
১।  Avoid Data Duplication and Code Reuse: জাভা একই কোড বার বার লিখা থেকে বাঁচিয়ে দেয়। যেমন ধরো, উপরে আমরা Human নামের ক্লাসটি যদি আরো কোথাও ইউজ করতে চাই সিমপ্লি ঐ ক্লাসের Object তৈরী করেই আমরা ইউজ করতে পারো। তুমি চাইলে Rakib, Sakib, Karim, Rahim নামের হাজার হাজার অবজেক্ট তৈরী করতে পারো। প্রতিটা অবজেক্টই স্বতন্ত্র।

২। Design Benefit: যেহেতু সোর্সকোড ক্যাটাগরিভিত্তিক থাকে এবং একই কোড বার বার লিখতে হয়না সেহেতু প্রোগ্রাম ডিজাইনে অনেক সুবিধা পাওয়া যায়।

৩। Simplicity: প্রোগ্রাম সহজে বুঝা এবং ডিবাগ করতে সুবিধা হয়।

৬। Software Maintenance: অবজেক্ট অরিয়েন্টেড প্রোগ্রামিং ব্যবহার করে সফটওয়্যার মেন্টেন করা যায় সহজেই। যে কারনে প্রফেসনাল কাজে অব্জেক্ট অরিয়েন্টেড প্রোগ্রামিং এর এতটা প্রয়োজন!

পরবর্তী পর্বগুলোতে আমরা আরো বিস্তারিত জানতে  পারবো এসব ব্যপারে।

অবজেক্ট অরিয়েন্টেড ফিচার্সঃ
১। Encapsulation
২। Inheritance
৩। Polymorphism
৪। Abstraction
৫। Interface

এখন নীচের প্রশ্নগুলোর উত্তর খোঁজার চেষ্টা করোঃ
১। জাভাতে কিভাবে অবজেক্ট তৈরী করা হয়?
২। উপরের প্রতিটা ক্লাসের কতগুলো অবজেক্ট তৈরি করা যাবে?
৩। উপরের দুইটা ক্লাস থেকে মোট ১০ টা অবজেক্ট তৈরি করো এবং ফাংশনে আলাদা আলাদা প্যারামিটার পাঠিয়ে পরিবর্তনটা লক্ষ্য কর!
৩। অবজেক্ট তৈরী করার সময় যে <ClassName()> এরকম কিছু একটা ব্যবহার করি সেটা কি?
৪। new কিওয়ার্ড এর কাজ কি?
৫। Constructor কি এবং কেন ব্যবহার করা হয়? এটা কিভাবে কাজ  করে?


প্র্যাক্টিসঃ
1. Create a class named Car. It includes the name of the car, Accelerates car speed, shows the current speed at any time.

Friday, February 23, 2018

ডাটা স্ট্রাকচার - ১ঃ ভেরিয়েবল, মেমরি অ্যাড্রেসিং এবং অ্যম্পারসেন্ড সমাচার

ছবিঃ সংগৃহীত


প্রোগ্রামিং করার করতে হলে ডাটা নিয়ে কাজ করতে হবেই। ডাটা বলার সাথে ডাটা ম্যানেজ করা বা সংরক্ষন করার একটা বিষয় চলে আসে। আর এই ডাটা ম্যানেজমেন্ট বা ডাটা রাখার ভিবিন্ন পদ্ধতির উপর ভিত্তি করে নানান ধরনের ডাটা স্ট্রাকচার আবিষ্কার হয়েছে। এগুলোর মধ্যে বেশ কিছু হল অ্যারে, লিঙ্ক লিস্ট, স্ট্যাক, কিউ, ট্রি, গ্রাফ! একেকটা ডাটা স্ট্রাকচারের একেক ধরনের সুবিধা। কোনটা কখন ব্যবহার করতে হবে তা সম্পূর্ন পরিস্থির উপর নির্ভর করে। ভিবিন্ন ডাটা স্ট্রাকচারের পাশাপাশি ডাটা স্ট্রাকচারের আর্কিটেকচার এবং মেমরি অ্যাড্রেস সম্পর্কে ধারনা থাকা চাই। কারন ডাটা স্ট্রাকচার, ডাটা এবং মেমরি পরস্পর পরস্পরের সাথে জড়িত। ডাটা স্ট্রাকচার; ডাটা এবং মেমরির সাথে যোগসূত্র স্থাপন করে। এই পর্বে এসব নিয়েই আলোচনা হবে।

প্রোগ্রামিং করার সময় আমাদের ভেরিয়েবল ডিক্লেয়ার করার দরকার হয়। এটার সাথে আমরা সবাই পরিচিত।  এটা ভেরিয়েবল হল ডাটা স্টোর করার সবচেয়ে সহজ এবং মৌলিক একটি পদ্ধতি। যা অন্য সব ডাটা স্ট্রাকচারের "মা"! অন্য সব ডাটা স্ট্রাকচারের মুল ভিত্তি হল ভেরিয়েবল।  কিন্তু ভেরিয়েবল এতটা গুরুত্বপুর্ন কেন? কেন এত ঝামেলার করার দরকার? আবার ইনপুট নেওয়ার সময় Scanf এর ভিতর অ্যাম্পারসেন্ড কেন ইউজ করতে হয়? এসব নিয়েই আজ ত্যানা পেছানো হবে-

ভেরিয়েবল হল ডাটা স্টোর করার সবচেয়ে সহজ এবং মৌলিক একটি পদ্ধতি। যা অন্য সব ডাটা স্ট্রাকচারের "মা"! অন্য সব ডাটা স্ট্রাকচারের মুল ভিত্তি হল ভেরিয়েবল। ভেরিয়েবল ছড়া কি প্রোগ্রামিং করা যাবেনা? উত্তর হল হ্যাঁ!  কিন্তু বেশ কিছু সমস্যা তোমাকে ফেস করতে হবে যার ফলে তুমি বেশীদুর এগোতে পারবানা। নীচের দুইটা প্রোগ্রাম খেয়াল করো। যেখানে আমি দুইটা সংখ্যার যোগ করেছি। একটাতে ভেরিয়েবল সহ আরেকটাতে ভেরিয়েবল ছাড়া।

Program - 1: Adding two numbers with variables

  #include <stdio.h>      
  int main()   
  {   
   int a, b, total; //declaring three variable to keep the data   
   a = 20;   
   b = 30;   
   total = a+b;   
   printf("Total: %d", total);  
   return 0;   
  }   

 OUTPUT  
 Total: 50  

Program - 2: Adding two numbers without variables 

 #include <stdio.h>   
 int main()  
 {  
   printf("%d\n", 20+30);  
   return 0;  
 }  

 OUTPUT  
 50  

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

Program - 3: Input two numbers from the user and Add it(With Variable)

  #include <stdio.h>     
  int main()    
  {    
   int a, b, total; //declaring three variable to keep the data    
   scanf("%d%d", &a, &b);  
   total = a+b;  
   printf("Total: %d", total);   
   return 0;    
  }   

 INPUT   
  10   
  20   
 OUTPUT   
  30   

Program - 3: Input two numbers from the user and Add it(Without Variable)

এই কাজটা কি আদো সম্ভব? ইউজারের কাছ থেকে ইনপুট নেওয়ার পর সেই নাম্বারটা আগে কোথাও সংরক্ষন করে রাখতে হবে। না রাখতে পারলে তো সেটা নিয়ে কাজ করা যাবেনা। আর ডাটাটা রাখার জন্যই ভেরিয়েবল বা কোন না কোন ডাটা স্ট্রাকচারের প্রয়োজন পড়ে। যে সিস্টেমের সাথে ইউজার ইন্টারেক্ট করতে পারবেনা সেই সিস্টেমের কোন দাম নাই। আর সেজন্যই ভেরিয়েবল ছাড়া প্রোগ্রামিং করার দৌড় এখানেই শেষ।

ভেরিয়েবল কিভাবে কাজ করেঃ

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

আমরা জানি কোন ডাটা রাখতে হলে মেমরির দরকার হয়। কিন্তু ভেরিয়েবলের কি কোন মেমরি আছে? সে কিভাবে ডাটা রাখে?  

আমরা যখন ভেরিয়েবল ডিক্লেয়ার করি তখন সে মেমরিতে যায়গা করে নেয়। আমরা আসলে ডাটা টা ভেরিয়েবলের মাধ্যমে মেমরিতে পাস করি। আমরা জানি যেকোন যায়গারই একটা অ্যাড্রেস থাকে। ভেরিয়েবল মেমরির কোন যায়গায়টা নিলো তারও একটা অ্যাড্রেস থাকে। ভেরিয়েবলের মেমরি অ্যাড্রেস দেখতে হলে তার আগে & দিয়ে প্রিন্ট করলেই দেখতে পাওয়া যাবে। এই অ্যাড্রেস হল একটা নাম্বার। নীচের প্রোগ্রামটিতে তিনটা ভেরিয়েবলের মেমরি অ্যাড্রেস দেখানো হয়েছে।

Program - 4: Check the memory address of two variables 

 #include<stdio.h>  
 int main()  
 {  
   int a, b, total;  
   printf("Memory Address of a: %d\n", &a);  
   printf("Memory Address of b: %d\n", &b);  
   printf("Memory Address of total: %d\n", &total);  
   return 0;  
 }  

 OUTPUT  
 Memory Address of a: 6356748  
 Memory Address of b: 6356744  
 Memory Address of total: 6356740  

এখানে & দিয়ে দুটো ভেরিয়েবলের মেমরি অ্যাড্রেস প্রিন্ট করেছি। মেমরি অ্যাড্রেসটা পিসি-পিসি ভেরি করতে পারে। তবে আউটপুট যাই আসুক সেটাই হল তোমার পিসির জন্য ঐ ভেরিয়েবলের মেমরি অ্যাড্রেস! উপরের আউটপুটটা আমার পিসির জন্য।

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

যেহেতু & মেমরি অ্যাড্রেস রিটার্ন করে সেহেতু আমরা &a, &b না ব্যবহার করে তাদের যে মেমরি অ্যাড্রেস পেলাম তা ব্যবহার করি! তাহলে কি কাজ করবে? নীচের প্রোগ্রামটি খেয়াল করো-

Program - 5: Input two numbers directly to the memory address 

 #include<stdio.h>  
 int main()  
 {  
   int a, b, total;  
   scanf("%d%d", 6356748,6356744);  
   total = a+b;  
   printf("%d", total);  
   return 0;  
 }  

 INPUT  
 10  
 20  
 OUTPUT  
 30  

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

যাইহোক, আমরা চাইলে এই মেমরি অ্যাড্রেসটা অন্য একটা ভেরিয়েবলে রেখেই কাজটা করতে পারি। মেমরি অ্যাড্রেস রাখার জন্য এক ধরনের বিশেষ ভেরিয়েবল আছে সি তে। এটাকে পয়েন্টার বলে। পয়েন্টার ডিক্লেয়ার করতে হয় * দিয়ে! নীচের প্রোগ্রামটি খেয়াল করো-

Program - 6: Input two numbers using pointers  

 #include<stdio.h>  
 int main()  
 {  
   int a, b, total;  //declaring variable   
   int *p1, *p2;   //declaring pointer variable   
   p1 = &a;      //keep the address of a to p1   
   p2 = &b;      //keep the address of b to p2    
   scanf("%d%d", p1,p2); //input the value to the memory location   
   total = a+b;  
   printf("%d", total);  
   return 0;  
 }  

 OUTPUT  
 Total: 50  

 INPUT  
 10  
 20  
 OUTPUT  
 30  

খেয়াল করো। ইনপুট নেওয়ার সময় আমরা এখানেও আর & ব্যবহার করছিনা। কারন p1 এবং p2 এর মধ্যেই মেমরি অ্যাড্রেস আছে।

আজ এই পর্যন্তই। আশাকরি ভেরিয়েবলের মেমরি অ্যাড্রেসিং এবং অ্যাম্পারসেন্ড এর কিচ্ছাকাহিনী থেকে কিছু একটা বুঝাতে সক্ষম হয়েছি। ধইন্যাপাতা