জাভা জেনেরিক্সে Bounded Type Parameters ব্যবহার করে আপনি নির্দিষ্ট সীমার মধ্যে টাইপ প্যারামিটারগুলোকে সংজ্ঞায়িত করতে পারেন। এটি নিশ্চিত করে যে জেনেরিক ক্লাস, মেথড বা ইন্টারফেস কেবলমাত্র নির্দিষ্ট টাইপ বা টাইপগুলোর সাবক্লাস ব্যবহার করতে পারবে।
Bounded Type Parameters এর সিনট্যাক্স:
<T extends SuperClass>
T extends SuperClass: এর মানে হলো,TহবেSuperClassবাSuperClassএর কোনো সাবক্লাস।- এটি শুধু ক্লাস নয়, ইন্টারফেস এর ক্ষেত্রেও প্রযোজ্য।
কেন Bounded Type Parameters দরকার?
- Constraints যোগ করা: নিশ্চিত করা যে নির্দিষ্ট টাইপ বা টাইপের সাবক্লাস ছাড়া অন্য কোনো টাইপ গ্রহণ করা যাবে না।
- Code Reusability বৃদ্ধি: নির্দিষ্ট টাইপের জন্য একই লজিক পুনরায় ব্যবহারযোগ্য।
- Type Safety নিশ্চিত করা: রানটাইম ত্রুটির সম্ভাবনা হ্রাস।
Bounded Type Parameters উদাহরণ:
১. Bounded Type Parameter সহ জেনেরিক ক্লাস:
class Box<T extends Number> {
private T item;
public void setItem(T item) {
this.item = item;
}
public T getItem() {
return item;
}
public double getDoubleValue() {
return item.doubleValue(); // Number এর মেথড
}
}
public class Main {
public static void main(String[] args) {
Box<Integer> intBox = new Box<>();
intBox.setItem(100);
System.out.println("Value: " + intBox.getItem());
System.out.println("Double Value: " + intBox.getDoubleValue());
Box<Double> doubleBox = new Box<>();
doubleBox.setItem(99.9);
System.out.println("Value: " + doubleBox.getItem());
System.out.println("Double Value: " + doubleBox.getDoubleValue());
// Box<String> stringBox = new Box<>(); // কম্পাইল টাইম ত্রুটি
}
}
আউটপুট:
Value: 100
Double Value: 100.0
Value: 99.9
Double Value: 99.9
২. Bounded Type Parameter সহ জেনেরিক মেথড:
public class GenericMethodExample {
public static <T extends Comparable<T>> T findMax(T x, T y) {
return (x.compareTo(y) > 0) ? x : y;
}
public static void main(String[] args) {
System.out.println("Max of 10 and 20: " + findMax(10, 20));
System.out.println("Max of A and B: " + findMax("A", "B"));
}
}
আউটপুট:
Max of 10 and 20: 20
Max of A and B: B
৩. Multiple Bounds:
class Example<T extends Number & Comparable<T>> {
private T value;
public Example(T value) {
this.value = value;
}
public boolean isGreaterThan(T other) {
return value.compareTo(other) > 0;
}
}
public class Main {
public static void main(String[] args) {
Example<Integer> example = new Example<>(10);
System.out.println("Is 10 greater than 5? " + example.isGreaterThan(5));
Example<Double> exampleDouble = new Example<>(15.5);
System.out.println("Is 15.5 greater than 20.0? " + exampleDouble.isGreaterThan(20.0));
// Example<String> exampleString = new Example<>("Test"); // কম্পাইল টাইম ত্রুটি
}
}
আউটপুট:
Is 10 greater than 5? true
Is 15.5 greater than 20.0? false
৪. Unbounded Wildcards (?) এবং Bounded Wildcards:
- Unbounded Wildcard (
?): যেকোনো টাইপ গ্রহণ করে। - Bounded Wildcards:
? extends T: উপরের দিকে সীমাবদ্ধতা।? super T: নিচের দিকে সীমাবদ্ধতা।
import java.util.ArrayList;
import java.util.List;
public class WildcardExample {
public static void printNumbers(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num);
}
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
List<Double> doubleList = new ArrayList<>();
doubleList.add(3.14);
doubleList.add(2.71);
printNumbers(intList);
printNumbers(doubleList);
}
}
আউটপুট:
1
2
3.14
2.71
Generics এবং Bounded Type Parameters এর সীমাবদ্ধতা:
Primitive টাইপ ব্যবহার করা যায় না:
int,doubleইত্যাদি সরাসরি জেনেরিক্সে ব্যবহার করা যায় না। তবে, Autoboxing এর মাধ্যমেInteger,Doubleব্যবহার করা যায়।List<int> list = new ArrayList<>(); // ত্রুটি List<Integer> list = new ArrayList<>(); // সঠিকMultiple Inheritance Allowed নয়: টাইপ প্যারামিটার একাধিক ক্লাস এক্সটেন্ড করতে পারে না। তবে, একটি ক্লাস এবং একাধিক ইন্টারফেস এক্সটেন্ড করা যায়।
<T extends ClassA & Interface1 & Interface2> // সঠিক- Runtime Type Erasure: Generics কম্পাইল টাইমে কাজ করে; রানটাইমে টাইপের তথ্য মুছে ফেলা হয়। তাই টাইপ প্যারামিটার রানটাইমে সরাসরি জানা যায় না।
Bounded Type Parameters জাভা জেনেরিক্সের একটি শক্তিশালী বৈশিষ্ট্য যা কোডকে আরও রিডেবল, রিইউজেবল এবং টাইপ সেফ করে। এটি জেনেরিক ক্লাস এবং মেথডগুলিকে একটি নির্দিষ্ট টাইপ বা টাইপের সাবক্লাসের জন্য সীমাবদ্ধ করে আরও সুনির্দিষ্ট কাজ করার সুযোগ দেয়।
Bounded Type Parameters হল Java Generics-এর একটি ফিচার যা টাইপ প্যারামিটারকে নির্দিষ্ট একটি শ্রেণি বা ইন্টারফেসের মধ্যে সীমাবদ্ধ করে। এটি টাইপ প্যারামিটারকে একটি নির্দিষ্ট সীমার মধ্যে কাজ করতে বাধ্য করে।
Bounded Type Parameters এর সিনট্যাক্স
Bounded Type Parameters নির্ধারণ করার জন্য extends কীওয়ার্ড ব্যবহার করা হয়। এটি টাইপ প্যারামিটারকে একটি নির্দিষ্ট ক্লাস বা ইন্টারফেস এবং তার সাবক্লাসের মধ্যে সীমাবদ্ধ করে।
class ClassName<T extends SuperClass> {
// Class Definition
}
উদাহরণ:
public class GenericClass<T extends Number> {
private T value;
public GenericClass(T value) {
this.value = value;
}
public double getDoubleValue() {
return value.doubleValue();
}
}
// Usage:
GenericClass<Integer> intObj = new GenericClass<>(10);
System.out.println(intObj.getDoubleValue());
GenericClass<Double> doubleObj = new GenericClass<>(5.5);
System.out.println(doubleObj.getDoubleValue());
// GenericClass<String> strObj = new GenericClass<>("Hello"); // Compile-time Error
Bounded Type Parameters এর ধরণ
Upper Bound (
T extends SomeClass)
টাইপ প্যারামিটার হবে নির্দিষ্ট ক্লাস বা ইন্টারফেস এবং তার সাবক্লাস।উদাহরণ:
public static <T extends Number> double add(T a, T b) { return a.doubleValue() + b.doubleValue(); } public static void main(String[] args) { System.out.println(add(5, 10)); // Valid System.out.println(add(3.5, 2.5)); // Valid // System.out.println(add("5", "10")); // Compile-time Error }Multiple Bounds (
T extends Class & Interface)
টাইপ প্যারামিটার একাধিক শ্রেণি বা ইন্টারফেসের সীমার মধ্যে থাকতে পারে।উদাহরণ:
public class GenericClass<T extends Number & Comparable<T>> { private T value; public GenericClass(T value) { this.value = value; } public boolean isGreaterThan(T other) { return value.compareTo(other) > 0; } }Unbounded Type (
T)
কোন সীমাবদ্ধতা নেই; যে কোনো টাইপ ব্যবহার করা যায়।উদাহরণ:
public static <T> void print(T value) { System.out.println(value); }
Bounded Type Parameters এর প্রয়োজনীয়তা
- কোড রিইউজেবিলিটি বৃদ্ধি করা
Bounded Type Parameters ব্যবহার করে একই কোড বিভিন্ন ক্লাসের জন্য ব্যবহার করা যায়, তবে নির্দিষ্ট টাইপের জন্য সীমাবদ্ধতা থাকে। টাইপ সেফটি নিশ্চিত করা
নির্দিষ্ট সীমার বাইরে কোন টাইপ ব্যবহার করতে গেলে compile-time এ এরর দেখা যায়।public static <T extends Number> void printSquare(T number) { System.out.println(number.doubleValue() * number.doubleValue()); } // Usage: printSquare(5); // Valid printSquare(3.14); // Valid // printSquare("Hello"); // Compile-time Error- কোডের কার্যক্ষমতা বৃদ্ধি করা
টাইপ চেকিং compile-time এ নিশ্চিত করায় runtime errors এর সম্ভাবনা কমে যায়। - প্রাসঙ্গিক অপারেশন সীমাবদ্ধ করা
Bounded Type Parameters ব্যবহার করে কেবল প্রাসঙ্গিক অপারেশনগুলো সীমাবদ্ধ করা যায়, যেমন একটি নির্দিষ্ট ক্লাসের মেথড বা ফিল্ড ব্যবহার। - মাল্টিপল টাইপ ইমপ্লিমেন্টেশন সহজ করা
একাধিক ক্লাস বা ইন্টারফেসের মিশ্রণ দিয়ে টাইপ প্যারামিটার বাউন্ড করা যায়।
Wildcard এবং Bounded Type Parameters
Bounded Wildcard (? extends T বা ? super T) ব্যবহার করে Generics-এ আরও বেশি ডাইনামিক সুবিধা পাওয়া যায়।
উদাহরণ: Upper Bound Wildcard
public static void printList(List<? extends Number> list) {
for (Number num : list) {
System.out.println(num);
}
}
উদাহরণ: Lower Bound Wildcard
public static void addToList(List<? super Integer> list) {
list.add(10);
list.add(20);
}
সারসংক্ষেপ
- Bounded Type Parameters টাইপ প্যারামিটারকে একটি নির্দিষ্ট ক্লাস বা ইন্টারফেস এবং তার সাবটাইপের মধ্যে সীমাবদ্ধ করে।
- এটি টাইপ সেফটি নিশ্চিত করে এবং compile-time এ টাইপ চেকিং করতে সাহায্য করে।
- কোড পুনঃব্যবহারযোগ্য এবং কার্যকর করে তোলে।
- Generics এর কার্যকারিতা বাড়াতে এটি অপরিহার্য।
Generics-এ bounded type parameters ব্যবহার করা হয় একটি নির্দিষ্ট টাইপ বা টাইপ রেঞ্জ সীমাবদ্ধ করতে। এভাবে আমরা টাইপ প্যারামিটারগুলোর সাথে আরও নির্দিষ্ট নিয়ম প্রয়োগ করতে পারি।
Upper Bounded Type Parameter
Upper bounded টাইপ প্যারামিটার একটি টাইপকে নির্ধারিত ক্লাস বা ইন্টারফেস (এবং তার সাবক্লাস/ইমপ্লিমেন্টেশন) এর মধ্যে সীমাবদ্ধ করে। এটি extends কীওয়ার্ড ব্যবহার করে ঘোষণা করা হয়।
সিনট্যাক্স:
<T extends ClassName>
উদাহরণ:
import java.util.ArrayList;
import java.util.List;
public class Main {
// Upper Bounded Generics Method
public static double sumOfNumbers(List<? extends Number> list) {
double sum = 0.0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum;
}
public static void main(String[] args) {
List<Integer> intList = new ArrayList<>();
intList.add(10);
intList.add(20);
intList.add(30);
List<Double> doubleList = new ArrayList<>();
doubleList.add(5.5);
doubleList.add(10.5);
System.out.println("Sum of Integers: " + sumOfNumbers(intList));
System.out.println("Sum of Doubles: " + sumOfNumbers(doubleList));
}
}
আউটপুট:
Sum of Integers: 60.0
Sum of Doubles: 16.0
কী শিখলাম:
? extends Numberনির্দেশ করে যে লিস্টের টাইপNumberবা তার সাবক্লাস হতে হবে (যেমনInteger,Double)।- এটি ডেটা রিড করতে কার্যকর।
Lower Bounded Type Parameter
Lower bounded টাইপ প্যারামিটার একটি টাইপকে নির্দিষ্ট ক্লাস বা তার সুপারক্লাসের মধ্যে সীমাবদ্ধ করে। এটি super কীওয়ার্ড ব্যবহার করে ঘোষণা করা হয়।
সিনট্যাক্স:
<T super ClassName>
উদাহরণ:
import java.util.ArrayList;
import java.util.List;
public class Main {
// Lower Bounded Generics Method
public static void addNumbers(List<? super Integer> list) {
list.add(10);
list.add(20);
}
public static void main(String[] args) {
List<Number> numberList = new ArrayList<>();
addNumbers(numberList);
System.out.println("Number List: " + numberList);
}
}
আউটপুট:
Number List: [10, 20]
কী শিখলাম:
? super Integerনির্দেশ করে যে লিস্টের টাইপIntegerবা তার সুপারক্লাস হতে হবে (যেমনNumber,Object)।- এটি ডেটা যোগ করার ক্ষেত্রে কার্যকর।
Upper vs Lower Bounded
| বৈশিষ্ট্য | Upper Bounded | Lower Bounded |
|---|---|---|
| কীওয়ার্ড | extends | super |
| কাজের ধরন | রিডিং ডেটার জন্য কার্যকর | লেখার/ডেটা যোগ করার জন্য কার্যকর |
| টাইপ রেঞ্জ | নির্দিষ্ট ক্লাস বা তার সাবক্লাস | নির্দিষ্ট ক্লাস বা তার সুপারক্লাস |
Wildcard in Generics
? হলো একটি wildcard যা টাইপ প্যারামিটারকে নমনীয় করে। এটি ? extends এবং ? super এর মাধ্যমে টাইপ রেঞ্জ নির্ধারণ করতে ব্যবহৃত হয়।
উদাহরণ:
// Wildcard with Upper Bound
List<? extends Number> upperBoundList;
// Wildcard with Lower Bound
List<? super Integer> lowerBoundList;
- Upper Bounded: নির্দিষ্ট টাইপের উপরে টাইপ সীমাবদ্ধ করতে কার্যকর।
- Lower Bounded: নির্দিষ্ট টাইপের নিচে টাইপ সীমাবদ্ধ করতে কার্যকর।
- Wildcard: নমনীয় টাইপ ম্যানিপুলেশনের জন্য।
Generics এ Upper এবং Lower Bounded Type Parameters টাইপ নিরাপত্তা ও ফ্লেক্সিবিলিটি বাড়ায়। এটি বড় ও জটিল জাভা প্রোজেক্টে বিশেষভাবে গুরুত্বপূর্ণ।
জাভা জেনেরিক্সে Wildcards ব্যবহার করে জেনেরিক টাইপের আরও বেশি নমনীয়তা অর্জন করা যায়। বিশেষত, Bounded Wildcards ব্যবহার করে নির্দিষ্ট সীমার মধ্যে জেনেরিক টাইপগুলিকে সীমাবদ্ধ করা যায়। এটি ডেটা টাইপগুলির মাঝে আরও ভালো টাইপ সুরক্ষা এবং পুনঃব্যবহারযোগ্য কোড লিখতে সাহায্য করে।
Wildcards এবং এর ধরনসমূহ
Wildcards হল একটি প্রশ্নবোধক চিহ্ন (?), যা "কোনো টাইপ" বোঝায়। এটি তিনটি প্রধান ধরণের হতে পারে:
- Unbounded Wildcards (
?): যেকোনো টাইপ গ্রহণ করতে পারে। - Upper Bounded Wildcards (
? extends Type): নির্দিষ্ট টাইপ বা তার সাবটাইপ গ্রহণ করতে পারে। - Lower Bounded Wildcards (
? super Type): নির্দিষ্ট টাইপ বা তার সুপারটাইপ গ্রহণ করতে পারে।
১. Unbounded Wildcards (?)
? ব্যবহার করা হয় যখন জেনেরিক টাইপের কোনো নির্দিষ্ট সীমা দরকার নেই।
উদাহরণ:
import java.util.List;
public class Main {
public static void printList(List<?> list) {
for (Object obj : list) {
System.out.println(obj);
}
}
public static void main(String[] args) {
List<String> stringList = List.of("Java", "Generics", "Wildcard");
List<Integer> intList = List.of(1, 2, 3);
printList(stringList);
printList(intList);
}
}
২. Upper Bounded Wildcards (? extends Type)
? extends Type ব্যবহার করা হয় যেখানে জেনেরিক টাইপটি একটি নির্দিষ্ট টাইপের সাবক্লাস বা ইনটারফেস হতে হবে। এটি Covariant আচরণ প্রদান করে।
উদাহরণ:
import java.util.List;
public class Main {
// Method to calculate sum of a list of Numbers or its subclasses
public static double sumList(List<? extends Number> list) {
double sum = 0.0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum;
}
public static void main(String[] args) {
List<Integer> intList = List.of(1, 2, 3);
List<Double> doubleList = List.of(1.1, 2.2, 3.3);
System.out.println("Sum of intList: " + sumList(intList));
System.out.println("Sum of doubleList: " + sumList(doubleList));
}
}
আউটপুট:
Sum of intList: 6.0
Sum of doubleList: 6.6
৩. Lower Bounded Wildcards (? super Type)
? super Type ব্যবহার করা হয় যেখানে জেনেরিক টাইপটি একটি নির্দিষ্ট টাইপের সুপারক্লাস হতে হবে। এটি Contravariant আচরণ প্রদান করে।
উদাহরণ:
import java.util.List;
import java.util.ArrayList;
public class Main {
// Method to add elements into a list
public static void addElements(List<? super Integer> list) {
list.add(10);
list.add(20);
list.add(30);
}
public static void main(String[] args) {
List<Number> numberList = new ArrayList<>();
addElements(numberList);
System.out.println("Number List: " + numberList);
}
}
আউটপুট:
Number List: [10, 20, 30]
Bounded Wildcards এর সুবিধা
- Code Flexibility: এটি একই মেথড বা ক্লাসকে বিভিন্ন টাইপের জন্য ব্যবহারযোগ্য করে।
- Type Safety: টাইপ সুরক্ষা নিশ্চিত করে।
- Reuse of Code: একই লজিক বিভিন্ন টাইপের উপর প্রয়োগ করা যায়।
Wildcard Limitations
- Insertion Limitation:
? extendsএর ক্ষেত্রে নতুন উপাদান যোগ করা যায় না (কেবলমাত্রnullযোগ করা যায়)। - Complexity: প্রাথমিক পর্যায়ে Wildcards বুঝতে কিছুটা জটিল হতে পারে।
Wildcards এবং Bounded Types ব্যবহার করলে জেনেরিক কোড আরও বেশি শক্তিশালী এবং নমনীয় হয়। এগুলোর সঠিক ব্যবহার করলে টাইপ সুরক্ষা এবং কোড পুনঃব্যবহারযোগ্যতা বৃদ্ধি পায়।
Multiple Bounds জাভার জেনেরিক্সের একটি বৈশিষ্ট্য যা একটি টাইপ প্যারামিটারকে একাধিক শর্তে সীমাবদ্ধ করতে দেয়। এটি extends কীওয়ার্ড ব্যবহার করে প্রয়োগ করা হয় এবং একটি ক্লাস বা ইন্টারফেসের সংমিশ্রণকে নির্দেশ করে।
Multiple Bounds এর সংজ্ঞা
- একটি টাইপ প্যারামিটার একইসঙ্গে একটি ক্লাস এবং একাধিক ইন্টারফেস প্রসারিত করতে পারে।
সিনট্যাক্স:
<T extends ClassName & Interface1 & Interface2>- প্রথমে সর্বদা একটি ক্লাস থাকতে হবে (যদি প্রয়োজন হয়), এবং তারপর ইন্টারফেস থাকতে পারে।
Multiple Bounds এর উদাহরণ
1. ক্লাস এবং ইন্টারফেসের সংমিশ্রণ
interface Drivable {
void drive();
}
interface Maintainable {
void maintain();
}
class Vehicle {
void start() {
System.out.println("Vehicle started");
}
}
public class MultiBoundExample<T extends Vehicle & Drivable & Maintainable> {
private T obj;
public MultiBoundExample(T obj) {
this.obj = obj;
}
public void operate() {
obj.start();
obj.drive();
obj.maintain();
}
}
ব্যবহারের উদাহরণ:
class Car extends Vehicle implements Drivable, Maintainable {
@Override
public void drive() {
System.out.println("Car is driving");
}
@Override
public void maintain() {
System.out.println("Car is being maintained");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
MultiBoundExample<Car> example = new MultiBoundExample<>(car);
example.operate();
}
}
আউটপুট:
Vehicle started
Car is driving
Car is being maintained
2. শুধুমাত্র ইন্টারফেসের সংমিশ্রণ
interface Readable {
void read();
}
interface Writable {
void write();
}
class MultiBoundInterfaceExample<T extends Readable & Writable> {
private T obj;
public MultiBoundInterfaceExample(T obj) {
this.obj = obj;
}
public void process() {
obj.read();
obj.write();
}
}
ব্যবহারের উদাহরণ:
class Document implements Readable, Writable {
@Override
public void read() {
System.out.println("Reading the document");
}
@Override
public void write() {
System.out.println("Writing to the document");
}
}
public class Main {
public static void main(String[] args) {
Document doc = new Document();
MultiBoundInterfaceExample<Document> example = new MultiBoundInterfaceExample<>(doc);
example.process();
}
}
আউটপুট:
Reading the document
Writing to the document
নিয়ম এবং সীমাবদ্ধতা
ক্লাস সর্বদা প্রথমে থাকতে হবে:
<T extends Class & Interface1 & Interface2>ভুল:
<T extends Interface1 & Class>।একই সময়ে শুধুমাত্র একটি ক্লাস থাকতে পারে: একটি টাইপ প্যারামিটার একাধিক ক্লাস প্রসারিত করতে পারে না।
ভুল:
<T extends Class1 & Class2 & Interface>- অজানা টাইপের জন্য কাজ করে না: Multiple Bounds শুধুমাত্র টাইপ প্যারামিটার ডিফাইন করার সময় ব্যবহার করা যায়।
Multiple Bounds এর সুবিধা
- টাইপ-সেফটি: টাইপ প্যারামিটার নির্দিষ্ট ক্লাস এবং ইন্টারফেসে সীমাবদ্ধ করা যায়।
- ফ্লেক্সিবিলিটি: একই টাইপ প্যারামিটারের মাধ্যমে একাধিক কার্যকরীতা অর্জন করা যায়।
- রিডেবল এবং কার্যকরী কোড: কোড পরিষ্কার এবং সহজে ব্যবস্থাপনা করা যায়।
Multiple Bounds জেনেরিক্স ব্যবহার করে টাইপ প্যারামিটারগুলিকে আরো কার্যকরী এবং শক্তিশালী করে। এটি জাভায় টাইপ সেফ এবং রিইউজেবল কোড লেখার একটি উন্নত পদ্ধতি।
Read more