ইনহেরিট্যান্স

ইনহেরিট্যান্স #

উত্তরাধিকার সূত্রে প্রাপ্ত কোনো কিছুকে ইনহেরিট্যান্স বলে। বাপ ভালো রাষ্ট্রনেতা ছিল, তাই মেয়েও ভালো রাষ্ট্রনেতা হয়েছে- এটা হলো ইনহেরিট্যান্সের সফলতম উদাহরণ। এখানে গুণটা উত্তরাধিকার সূত্রে প্রাপ্ত।

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

class SuperCalculator:
    """Do addition, subtraction, multiplication, division, square and cube."""

    def addition(self, a, b):
        return a + b

    def subtraction(self, a, b):
        return a - b

    def multiplication(self, a, b):
        return a * b

    def division(self, a, b):
        try:
            return a / b
        except ZeroDivisionError:
            return 'It is impossible to divide by zero.'

    def square(self, a):
        return a * a

    def cube(self, a):
        return a * a * a

my_calculator = SuperCalculator()

temp = my_calculator.addition(23, 47)
print(temp)

temp = my_calculator.subtraction(87, 54)
print(temp)

temp = my_calculator.multiplication(65, 56)
print(temp)

temp = my_calculator.division(852, 76)
print(temp)

temp = my_calculator.square(7)
print(temp)

temp = my_calculator.cube(3)
print(temp)

আউটপুট

70
33
3640
11.210526315789474
49
27

অনেক কষ্ট করলাম আমরা। আচ্ছা আমাদের Calculator ক্লাসটার উপর ভিত্তি করে কোনকিছু করা গেলে কাজটা আরো সহজে হত না? ঐ ক্লাসে তো চারটা মেথড লেখাই আছে আমাদের। ওটার সাথে আর দুইটা মেথড যোগ করলেই কিন্তু কেল্লা ফতে!

class Calculator:
    """Do addition, subtraction, multiplication and division."""

    def addition(self, a, b):
        return a + b

    def subtraction(self, a, b):
        return a - b

    def multiplication(self, a, b):
        return a * b

    def division(self, a, b):
        try:
            return a / b
        except ZeroDivisionError:
            return 'It is impossible to divide by zero.'

class SuperCalculator(Calculator):
    """Child class of Calculator. Do square and cube."""

    def square(self, a):
        return a * a

    def cube(self, a):
        return a * a * a

my_calculator = SuperCalculator()

temp = my_calculator.addition(23, 47)
print(temp)

temp = my_calculator.subtraction(87, 54)
print(temp)

temp = my_calculator.multiplication(65, 56)
print(temp)

temp = my_calculator.division(852, 76)
print(temp)

temp = my_calculator.square(7)
print(temp)

temp = my_calculator.cube(3)
print(temp)

আউটপুট

70
33
3640
11.210526315789474
49
27

এখানে আমরা Calculator ক্লাসের উপর বেইস করে বা Calculator ক্লাসকে ইনহেরিট করে SuperCalculator নামে নতুন একটা ক্লাস তৈরি করেছি। নতুন ক্লাসের নামের পর () এর ভিতর যে ক্লাসগুলো থেকে ইনহেরিট করা হবে তাদের কমা সেপারেটেড লিস্ট দিতে হয়। আমরা শুধু একটা ক্লাস থেকে ইনহেরিট করেছি তাই শুধু একটা ক্লাসকে দিয়েছি। এই ক্লাসকে বেইস (base) ক্লাস বা প্যারেন্ট (parent) ক্লাস বলে। আর নতুন তৈরি ক্লাসকে বলে চাইল্ড (child) ক্লাস। এই চাইল্ড ক্লাসে প্যারেন্ট ক্লাসের সকল গুণাগুণ অক্ষুণ্ন থাকে। চাইল্ড ক্লাসের ইন্সট্যান্স বা অবজেক্ট থেকে প্যারেন্ট ক্লাসের সকল মেথড অ্যাক্সেস করা যায়।

যদিও আপাত দৃষ্টিতে মনে হচ্ছে ইনহেরিট করে কোন লাভ হয়নি। তবে সত্যি বলতে কি, লাভ হয়েছে। নানা সময়ে পাইথনে, বিভিন্ন ক্লাস ইনহেরিট করে আমাদের কাজ করতে হবে। যেমনটা করতে হয় ইউজার ডিফাইন্ড এক্সেপশন পয়দা করার সময়। এরর হ্যান্ডলিং চাপ্টারে আমরা বলেছিলাম পরে একসময় আমরা এই জিনিসটা শিখব। এখন সে সময় উপস্থিত। পাইথনে ইউজার ডিফাইন্ড এক্সেপশন প্রত্যক্ষ বা পরোক্ষভাবে Exception ক্লাস থেকে ডিরাইভ (derive) করতে হবে।

class CustomError(Exception):
    """Just for example."""

    def __init__(self, message):
        self.message = message

try:
    raise CustomError('It is a Custom Error.')
except CustomError as e:
    print(e)

আউটপুট

It is a Custom Error.

মেথড ওভাররাইডিং #

মেথড ওভাররাইডিং (overriding) একটা চমৎকার জিনিস। চাইল্ড ক্লাসে আমরা প্যারেন্ট ক্লাসের মেথডকে ওভাররাইড করে ঢেলে সাজাতে পারি। একেই মেথড ওভাররাইডিং বলে। একটা উদাহরণ দেখা যাক।

class Calculator:
    """Do addition, subtraction, multiplication and division."""

    def addition(self, a, b):
        return a + b

    def subtraction(self, a, b):
        return a - b

    def multiplication(self, a, b):
        return a * b

    def division(self, a, b):
        try:
            return a / b
        except ZeroDivisionError:
            return 'It is impossible to divide by zero.'

class SuperCalculator(Calculator):
    """Do addition, subtraction, multiplication, division, square and cube."""

    def addition(self, a, b, c):
        return a + b + c

    def square(self, a):
        return a * a

    def cube(self, a):
        return a * a * a

my_calculator = SuperCalculator()

temp = my_calculator.addition(23, 47, 12)
print(temp)

temp = my_calculator.subtraction(87, 54)
print(temp)

temp = my_calculator.multiplication(65, 56)
print(temp)

temp = my_calculator.division(852, 76)
print(temp)

temp = my_calculator.square(7)
print(temp)

temp = my_calculator.cube(3)
print(temp)

আউটপুট

82
33
3640
11.210526315789474
49
27

এখানে আমরা addition() মেথডকে ওভাররাইড করেছি। প্যারেন্ট ক্লাসে এই মেথড কেবল দুইটা সংখ্যাকে যোগ করতে পারত। আর চাইল্ড ক্লাসে এই মেথড তিনটা সংখ্যাকে যোগ করতে পারে। এই একই ভাবে ক্লাস কন্সট্রাক্টর __init__() কেও আমরা ওভাররাইড করতে পারি।

এবার বাড়ির কাজ। ক্লাস কন্সট্রাক্টর __init__() কে ওভাররাইড করে একটা সুপারক্যালকুলেটর ক্লাস বানিয়ে প্রোগ্রাম লিখতে হবে। পারা যাবে তো? অবশ্যই। কারণ, মানুষ আমাদের পাশে আছে।

মন্তব্য করুন