ক্লাস ইনহেরিটেন্স OOP (অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং)-এর একটি মৌলিক ফিচার যা আপনাকে যেকোনো ক্লাসের একটি আরও স্পেসিফিক এবং স্পেশালাইজড ভার্সন তৈরি করতে সাহায্য করে।
এখানে একটি উদাহরণ:
Food -> Fruit -> Orange
এই ক্লাসগুলোর মধ্যে একটি সম্পর্ক রয়েছে!
আমরা বলতে পারি একটি কমলা একটি ফল, কিন্তু ফলগুলোরাও খাদ্য।
প্যারেন্ট ক্লাস (কে সুপার ক্লাস বা বেস ক্লাসও বলা হয়) সর্বদা সাবক্লাসের চেয়ে বেশি জেনেরিক।
Fruit (আরও জেনেরিক) হল Orange (আরও স্পেসিফিক)-এর প্যারেন্ট ক্লাস।
রুবিতে এটি এইভাবে দেখায়:
class Food end class Fruit < Food end class Orange < Fruit end
ইনহেরিটেন্স-এর রুবিতে একটি ইমপ্লিকেশন হল যে Food-এ ডিফাইন করা প্রতিটি মেথড এবং কনস্ট্যান্ট Fruit-এ উপলব্ধ থাকবে, এবং Orange-এও।
মেথডগুলো বেস ক্লাস থেকে পাস ডাউন হয়, কিন্তু অন্য দিকে নয়।
ইনহেরিটেন্সর উদ্দেশ্য কী?
আপনি ভাবতে পারেন যে একটি অবজেক্ট হায়ারার্কি তৈরি করা আপনার কোডের জন্য 일종의 “ফিল গুড” অর্গানাইজেশন দেয়, কিন্তু এর চেয়ে অনেক বেশি কিছু রয়েছে।
ইনহেরিটেন্স ব্যবহার করা হয় একটি প্যারেন্ট ক্লাসের একটি ভিন্ন ভার্সন তৈরি করতে যা একটি নির্দিষ্ট উদ্দেশ্যের জন্য ফিট। হতে পারে এটিকে কিছু এক্সট্রা ফিচার বা মেথড দরকার যা প্যারেন্ট ক্লাসে অর্থহীন হত।
এখানে একটি উদাহরণ:
সকল ফলের রঙ, ওজন, এবং নাম থাকে।
কিছু ফলের বিশেষ বৈশিষ্ট্য থাকতে পারে যা অন্যান্য ফলের সাথে শেয়ার করা নয়, তাই আপনি একটি নতুন ক্লাস তৈরি করুন যা সকল ফলের বৈশিষ্ট্য (রঙ, ওজন, ইত্যাদি) ইনহেরিট করে এবং তারপর সেই 스페শ্যাল ক্যারেক্টারিস্টিক যোগ করুন।
এটিই আমার স্পেশালাইজেশন বলার অর্থ।
আরেকটি উদাহরণ:
আপনার কাছে একটি ক্লাস আছে যা ডেটাবেসে লিখে, কিন্তু আপনি ক্লাসটির একটি অন্য ভার্সন চান (হয়তো ডিবাগিং উদ্দেশ্যে) যা সকল ডেটাবেস অপারেশন লগ করে।
এই কেসে, আপনি ডেকোরেটর প্যাটার্ন চান।
আপনি এই আর্টিকেলে বিস্তারিত ব্যাখ্যা পড়তে পারেন, কিন্তু বেসিক আইডিয়া হল যে আপনি ইনহেরিটেন্স ব্যবহার করুন অন্য একটি ক্লাস র্যাপ করতে এবং তারপর কিছু নতুন জিনিস যোগ করতে।
মূল ক্লাস পরিবর্তন করা ছাড়া!
রিয়েল ওয়ার্ল্ডে ইনহেরিটেন্স
ঠিক আছে।
আমরা ইনহেরিটেন্স সম্পর্কে শিখেছি, কিন্তু আপনি কি জানতেন যে আপনি একটি রুবি ডেভেলপার হিসেবে প্রতিদিন এটি ব্যবহার করছেন?
রুবি নিজে ইনহেরিটেন্স ব্যবহার করে নিচের মেথডগুলো সক্ষম করতে:
putsclasssuper
এটি কারণ সকল রুবি অবজেক্ট ডিফল্টভাবে Object ক্লাস থেকে ইনহেরিট করে।
তাই আপনি যদি এমন একটি ক্লাস তৈরি করেন:
class Apple end
তার প্যারেন্ট ক্লাস হল Object:
Apple.superclass # Object
সেজন্য আপনি উপরের মেথডগুলোর মতো মেথড ব্যবহার করতে পারেন।
উদাহরণস্বরূপ, যখন আপনি puts কল করেন, রুবি এই মেথডটি আপনার ক্লাসে খুঁজে বের করে।
তারপর:
- এটি প্যারেন্ট ক্লাসগুলোর একে একে মেথডটি খুঁজে বের করে
- যদি না পায়, তবে আবার অবজেক্ট থেকে শুরু করে
method_missingখুঁজে বের করার চেষ্টা করে - যদি তবুও না পায়, তবে এটি একটি
NoMethodErrorবাNameErrorরেইজ করবে যদি মেথডটি এক্সপ্লিসিট অবজেক্ট ছাড়া কল করা হয় (a.sizevssize, যেখানেaহল এক্সপ্লিসিট অবজেক্ট)
রেইলসে ইনহেরিটেন্সের আরও উদাহরণ খুঁজে পাবেন।
এখানে:
class ApplicationController < ActionController::Base end
Controller:
class SessionsController < ApplicationController end
Model:
class Comment < ApplicationRecord belongs_to :article end
ইনহেরিটেন্স রুবির सर्वত্রে আছে, কিন্তু কখনও কখনও এটি সঠিক সমাধান নয়।
কম্পোজিশন: ইনহেরিটেন্সের একটি বিকল্প
ইনহেরিটেন্সের কিছু সীমাবদ্ধতা রয়েছে।
উদাহরণস্বরূপ:
আপনি পার্টস থেকে একটি কম্পিউটার বানাতে চান।
আমরা বলি কম্পিউটারের পার্টস আছে, কিন্তু আপনাদের পার্টস নিজস্বভাবে কম্পিউটার নয়।
আপনি যদি সেগুলো আলাদা করেন, তারা তাদের ফাংশন করতে পারবে না।
আমাদের অন্য কিছু দরকার…
আমাদের কম্পোজিশন দরকার!
কম্পোজিশন ক্লাস বানায় যেখানে ভিন্ন পার্টস একসাথে আসে একটি ফাংশন পারফর্ম করতে।
ইতিপূর্বে কম্পিউটারের মতো।
এখানে কম্পোজিশন একশনের একটি উদাহরণ:
class Computer def initialize(memory, disk, cpu) @memory = memory @disk = disk @cpu = cpu end end
কম্পিউটারকে এটি কাজ করার জন্য যেসব পার্ট দরকার সেগুলো দেওয়া হয়েছে।
এটিই কম্পোজিশন।
লিস্কোভ সাবস্টিটিউশন প্রিন্সিপল
ইনহেরিটেন্স সঠিক পরিস্থিতিতে ব্যবহার করলে শক্তিশালী।
অন্য সব টুলের মতো এটিও অপব্যবহার করা যায়!
বস্তুতঃ, মূল ডিজাইন প্যাটার্ন বই থেকে একটি জনপ্রিয় উদ্ধৃতি আছে যেটি এইভাবে যায়:
“Prefer composition over inheritance.”
Design Patterns: Elements of Reusable Object-Oriented Software
নিশ্চিত করতে যে আপনি ইনহেরিটেন্স সঠিকভাবে ব্যবহার করছেন একটি প্রিন্সিপল আপনি ফলো করতে পারেন, SOLID-এর L।
এটি står “Liskov Substitution Principle”-এর জন্য।
এটি বলে আপনার সাবক্লাসগুলো আপনার বেস ক্লাসের জায়গায় ব্যবহার করা যেতে পারা উচিত।
অন্য কথায়:
আপনি Fruit-এর থেকে ইনহেরিট করলে এবং color একটি স্ট্রিং হলে, আপনি একটি সাবক্লাসে color-কে একটি সিম্বল রিটার্ন করতে চাইবেন না।
উদাহরণ:
Fruit-এর ব্যবহারকারীরা color-এর স্ট্রিং রিটার্ন করার ওপর নির্ভর করে।
class Fruit def color "orange" end end
এটি LSP ভাঙে:
class Orange < Fruit def color :orange end end
আপনি color-কে সিম্বল রিটার্ন করতে পরিবর্তন করলে, আপনি একটি Fruit অবজেক্টকে Orange দিয়ে রিপ্লেস করতে পারবেন না।
কেন?
কারণ আপনি যদি একটি সিম্বলে split মেথড কল করেন তবে আপনি একটি এরর পাবেন।
এটি একটি মেথড যা সিম্বলগুলোর নেই।
কিন্তু স্ট্রিংগুলোর আছে।
একটি আর রেড ফ্ল্যাগ হল যখন আপনার সাবক্লাস প্যারেন্ট ক্লাসের একটি সত্য স্পেশালাইজেশন নয় এবং আপনি শুধু ইউটিলিটি মেথড শেয়ার করার জন্য প্যারেন্ট ক্লাস ব্যবহার করছেন।
সারাংশ
আপনি রুবিতে ইনহেরিটেন্স এবং কম্পোজিশন সম্পর্কে শিখেছেন!
আপনি ইনহেরিটেন্স ব্যবহার করতে পারেন একটি প্যারেন্ট ক্লাসের স্পেশালাইজড ভার্সন তৈরি করতে, এবং কম্পোজিশন ব্যবহার করতে পারেন কম্পোনেন্টগুলোকে একসাথে ফিট করে একটি হোল বানাতে। LSP প্রিন্সিপল ফলো করুন যদি আপনি গুলিয়ে ফেলতে না চান।
এখন আপনি ভালো অবজেক্ট-ওরিয়েন্টেড কোড লিখতে পারেন 🙂
পড়ার জন্য ধন্যবাদ।