ইনহেরিটেন্স (Inheritance) হল দুটি ক্লাসের মধ্যে একটি সম্পর্ক যেখানে একটি ক্লাস অন্য ক্লাসের প্রোপার্টি ইনহেরিট করে। এই সম্পর্ক `extends` কীওয়ার্ড দিয়ে ডিফাইন করা হয়:
public class A extends B { }
যে ক্লাস ইনহেরিট করে সেটিকে সাব ক্লাস (sub class) বা চাইল্ড ক্লাস (child class) বলা হয় এবং যার প্রোপার্টি ইনহেরিট করা হয় সেটিকে সুপার ক্লাস (super class) বা প্যারেন্ট ক্লাস (parent class) বলা হয়।
ইনহেরিটেন্সে সুপার ক্লাসের মেম্বারগুলোর একটি কপি সাব ক্লাস অবজেক্টে তৈরি হয়। তাই সাব ক্লাস অবজেক্ট ব্যবহার করে দুটি ক্লাসের মেম্বার অ্যাক্সেস করা যায়।
মাল্টিপল ইনহেরিটেন্স (Multiple Inheritance)
ইনহেরিটেন্সের বিভিন্ন ধরন আছে: সিঙ্গল (single), মাল্টিলেভেল (multilevel), হায়ারার্কিক্যাল (hierarchical), মাল্টিপল (multiple) এবং হাইব্রিড (hybrid)।
মাল্টিপল ইনহেরিটেন্সে একটি ক্লাস একাধিক ক্লাসের প্রোপার্টি ইনহেরিট করে। অন্য কথায়, মাল্টিপল ইনহেরিটেন্সে এক চাইল্ড ক্লাস এবং n সংখ্যক প্যারেন্ট ক্লাস থাকতে পারে। জাভা ক্লাসের সাথে মাল্টিপল ইনহেরিটেন্স সাপোর্ট করে না।
ডায়ামন্ড সমস্যা (The Diamond Problem)
উদাহরণস্বরূপ, ধরুন জাভা মাল্টিপল ইনহেরিটেন্স সাপোর্ট করে। সেই অনুমানের সাথে নিচের উদাহরণটি বিবেচনা করুন।
উদাহরণ
এখানে আমাদের একটি অ্যাবস্ট্র্যাক্ট ক্লাস আছে নাম Sample যার একটি অ্যাবস্ট্র্যাক্ট মেথড:
public abstract class Sample {
public abstract void demo();
}
একই প্যাকেজ/ফোল্ডারে এই ক্লাসকে এক্সটেন্ড করে দুটি ক্লাস আছে এবং তারা অ্যাবস্ট্র্যাক্ট মেথড demo() ইমপ্লিমেন্ট করার চেষ্টা করছে।
public class Super1 extends Sample {
public void demo() {
System.out.println("demo method of super1");
}
}
public class Super2 extends Sample {
public void demo() {
System.out.println("demo method of super2");
}
}
আমাদের অনুমান অনুযায়ী, যেহেতু জাভা মাল্টিপল ইনহেরিটেন্স সাপোর্ট করে, আমরা Super1 এবং Super2 উভয়ই ইনহেরিট করার চেষ্টা করছি।
public class SubClass extends Super1, Super2 {
public static void main(String args[]) {
SubClass obj = new SubClass();
obj.demo();
}
}
ইনহেরিটেন্সের বেসিক নিয়ম অনুযায়ী, demo() মেথডের দুটি কপি সাব ক্লাস অবজেক্টে তৈরি হবে যা সাব ক্লাসকে একই প্রোটোটাইপ (নেম আর আর্গুমেন্ট) দিয়ে দুটি মেথড দিয়ে ছেড়ে দেবে। তারপর যদি সাব ক্লাস অবজেক্ট দিয়ে demo() মেথড কল করা হয়, কম্পাইলার দ্বিধাগ্রস্ত হয়ে যায় কোন মেথড কল করতে হবে। এই সমস্যাটিই জাভায় ডায়ামন্ড সমস্যা (diamond problem) হিসেবে পরিচিত।

এই কারণেই জাভা মাল্টিপল ইনহেরিটেন্স সাপোর্ট করে না অর্থাৎ, আপনি একাধিক ক্লাস এক্সটেন্ড করতে পারবেন না। এখনও যদি চেষ্টা করেন, তবে কম্পাইল টাইম এরর জেনারেট হবে।
কম্পাইল টাইম এরর
উপরোক্ত প্রোগ্রাম কম্পাইল করলে নিচের এরর দেখায়:
MultipleInheritanceExample.java:9: error: '{' expected
public class MultipleInheritanceExample extends MyInterface1, MyInterface2 {
^ 1 error
সমাধান
আপনি জাভাতে ডিফল্ট মেথড (Java 8) এবং ইন্টারফেস ব্যবহার করে মাল্টিপল ইনহেরিটেন্স অর্জন করতে পারেন।
Java 8 থেকে ডিফল্ট মেথড (default methods) ইন্টারফেসে ইন্ট্রোডিউস করা হয়েছে। অন্যান্য অ্যাবস্ট্র্যাক্ট মেথডের विपরীত এই মেথডগুলো ইন্টারফেসের মেথড যাদের একটি ডিফল্ট ইমপ্লিমেন্টেশন আছে। যদি ইন্টারফেসে ডিফল্ট মেথড থাকে, তবে সেই ইন্টারফেস ইমপ্লিমেন্ট করা ক্লাসগুলোতে এটি ওভাররাইড করা (বডি দেওয়া) বাধ্যতামূলক নয়।
আপনি দুটি আলাদা ইন্টারফেসে একই ডিফল্ট মেথড (একই নাম ও সিগনেচার) রাখতে পারেন এবং একটি ক্লাস থেকে এই দুটি ইন্টারফেস ইমপ্লিমেন্ট করতে পারেন।
যদি আপনি এसा করেন, তবে আপনাকে অবশ্যই ক্লাস থেকে ডিফল্ট মেথডটি eksplisittly স্পেসিফাই করে ওভাররাইড করতে হবে ইন্টারফেসের নামসহ।
উদাহরণ
interface MyInterface1 {
public static int num = 100;
public default void display() {
System.out.println("display method of MyInterface1");
}
}
interface MyInterface2 {
public static int num = 1000;
public default void display() {
System.out.println("display method of MyInterface2");
}
}
public class InterfaceExample implements MyInterface1, MyInterface2 {
public void display() {
MyInterface1.super.display();
// অথবা,
MyInterface2.super.display();
}
public static void main(String args[]) {
InterfaceExample obj = new InterfaceExample();
obj.display();
}
}
আউটপুট
display method of MyInterface1 display method of MyInterface2