Vivasoft-logo

4.3 জেনেরিক ক্লাস ও এক্সটেন্ডিং জেনেরিক ক্লাস

জেনেরিক ফাংশন বা ইন্টারফেসের মতই একটি জেনেরিক ক্লাসের নামের পর এঙ্গেল ব্র্যাকেটে (<>) এক বা ততোধিক  টাইপ প্যারামিটার ডিফাইন করা থাকে। জেনেরিক ক্লাসের একটি উদাহরন দেখে নেয়া যাক:

				
					class GenericExample<NumType, StringType> {
  numberValue: NumType;
  stringValue: StringType;

   constructor(numberValue: NumType, stringValue: StringType) {
      this.numberValue = numberValue;
      this.stringValue = stringValue;
   }
}
				
			

লক্ষ করুন GenericExample ক্লাসে  NumType এবং StringType দুইটি  জেনেরিক টাইপ প্যারামিটার ব্যবহার  করা হয়েছে। এই টাইপ প্যারামিটার দুটোকে ক্লাসের অন্যান্য প্রোপার্টি এবং কন্সট্রাক্টর ব্যবহার করতে পারবে। ক্লাসটি ব্যবহার  করা যায় এভাবে:

				
					let myGenericExample = new GenericExample<number, string>(0, 'Hello');

console.log(myGenericExample.numberValue); // prints 0
console.log(myGenericExample.stringValue); // prints 'Hello'
				
			

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

এক্সটেন্ডিং জেনেরিক ক্লাস:

আমরা জেনেরিক ক্লাস এক্সটেন্ড করার মাধ্যমে ক্লাসে কিছু ফিচার যোগ করতে পারি। একটি জেনেরিক ক্লাস এক্সটেন্ড অপারেটরের মাধ্যমে এক্সটেন্ড করা যায় । প্রথমে একটি জেনেরিক ক্লাস তৈরি করা যাক: 

				
					interface Product {
  name: string;
  price: number;
}

class Store<T> {
  protected _object: T[] = [];
 
  add(obj: T): void {
    this._object.push(obj)
  }
}
				
			

এখানে ক্লাসের ভেতরে একটি অবজেক্ট এবং একটি মেথড ডিক্লার করা হয়েছে যা T টাইপের ভ্যালু অবজেক্ট এ পুশ করবে। অবজেক্টটিতে protected কিওয়ার্ড ব্যবহার  করা হয়েছে যেন এর প্রোপার্টি সাবক্লাস থেকে এক্সেস করা যায়।

				
					class StoreSubclass<T> extends Store<T>{
    // StoreSubclass method here
}
				
			

এখন ধরা যাক আমরা একটি সাবক্লাস থেকে বেজক্লাস _object এর এলিমেন্ট এক্সেস করতে চাচ্ছি। এটি করার জন্য একটি মেথড ডিফাইন করা যাক।

				
					class StoreSubclass1<T> extends Store<T> {
 findMethod(name: string): T | undefined {
    return this._object.find(obj => obj.name === name)
  }
  // Property 'name' does not exist on type 'T[]'.
}
				
			

আমরা মেথডের ভেতর থেকে এভাবে ডট নোটেশন ব্যবহার  করে অবজেক্ট এর ভ্যালু এক্সেস করতে পারবো না। সেক্ষেত্রে কম্পাইলেশন এরর দেখাবে। যেমন: এখানে সাবক্লাসের প্যারামিটার <T> জানে না অবজেক্ট এ name নামের প্রোপার্টি আছে। সেক্ষেত্রে আমাদের সাবক্লাসের প্যারামিটারে স্পেসিফাই করে দিতে হবে এভাবে।

				
					class StoreSubclass1<T extends { name: string }> extends Store<T>{
 findMethod(name: string): T | undefined {
    return this._object.find(obj => obj.name === name)
  }
}
				
			

অন্যদিকে আমরা যদি সাবক্লাসকে জেনেরিক করতে না চাই তাহলে জেনেরিক টাইপ প্যারামিটার ফিক্স করে দিতে পারবো। যেমন:

				
					class fixedStore extends Store<Product> {
  identity(category: string): Product[] {
    return [];
  }
}
				
			

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