مقدمه

یکی از اصول قدرتمند برنامه‌نویسی شیءگرا، «وراثت» یا Inheritance است. وراثت به ما اجازه می‌دهد تا یک کلاس جدید (که به آن «کلاس فرزند» یا child class می‌گویند) بسازیم که تمام اتریبیوت‌ها و متدهای یک کلاس موجود (که به آن «کلاس والد» یا parent class می‌گویند) را به ارث ببرد. کلاس فرزند تمام قابلیت‌های کلاس والد را در اختیار دارد و علاوه بر آن، می‌تواند اتریبیوت‌ها و متدهای جدیدی مختص به خود داشته باشد یا متدهای والد را بازنویسی (override) کند.

این کار به ما کمک می‌کند تا از تکرار کد جلوگیری کرده و یک سلسله‌مراتب منطقی بین کلاس‌های مرتبط ایجاد کنیم.

ایجاد یک کلاس فرزند

برای ایجاد یک کلاس فرزند، هنگام تعریف آن، نام کلاس والد را در داخل پرانتز قرار می‌دهیم. بیایید با استفاده از کلاس Car از درس قبل، یک کلاس فرزند به نام ElectricCar بسازیم.

Copy Icon PYTHON
class Car:
    # ... (previous Car class definition) ...

class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
    
    def __init__(self, make, model, year):
        """Initialize attributes of the parent class."""
        super().__init__(make, model, year)

my_tesla = ElectricCar('tesla', 'model s', 2024)
print(my_tesla.get_descriptive_name()) # This method is inherited from Car

تابع super()

خط super().__init__(make, model, year) یک بخش کلیدی است. تابع super() یک تابع خاص است که به شما اجازه می‌دهد تا به متدهای کلاس والد ارجاع دهید. در اینجا، ما سازنده (__init__) کلاس Car را فراخوانی می‌کنیم تا مطمئن شویم که تمام اتریبیوت‌های تعریف شده در کلاس والد، به درستی برای نمونه ElectricCar نیز مقداردهی اولیه می‌شوند.

تعریف اتریبیوت‌ها و متدهای جدید برای کلاس فرزند

پس از اینکه کلاس فرزند را ساختیم، می‌توانیم اتریبیوت‌ها و متدهای جدیدی که فقط مختص به آن هستند را اضافه کنیم. برای مثال، یک خودروی الکتریکی یک باتری دارد که خودروی معمولی ندارد.

Copy Icon PYTHON
class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
    
    def __init__(self, make, model, year):
        """
        Initialize attributes of the parent class.
        Then initialize attributes specific to an electric car.
        """
        super().__init__(make, model, year)
        self.battery_size = 40 # New attribute

    def describe_battery(self):
        """Print a statement describing the battery size."""
        print(f"This car has a {self.battery_size}-kWh battery.")

my_tesla = ElectricCar('tesla', 'model s', 2024)
my_tesla.describe_battery()

در این نسخه، ما سازنده کلاس فرزند را طوری تغییر داده‌ایم که علاوه بر فراخوانی سازنده والد، یک اتریبیوت جدید به نام battery_size را نیز مقداردهی کند. همچنین یک متد جدید به نام describe_battery برای توصیف این اتریبیوت اضافه کرده‌ایم.

بازنویسی متدهای کلاس والد (Overriding)

شما می‌توانید هر متدی از کلاس والد را که با نیازهای کلاس فرزند شما مطابقت ندارد، بازنویسی (override) کنید. برای این کار، کافیست یک متد با همان نام در کلاس فرزند تعریف کنید. پایتون همیشه ابتدا به دنبال متد در کلاس فرزند می‌گردد و اگر آن را پیدا نکند، به سراغ کلاس والد می‌رود.

برای مثال، فرض کنید کلاس Car یک متد به نام fill_gas_tank() دارد. این متد برای یک خودروی الکتریکی معنایی ندارد، بنابراین ما می‌توانیم آن را در کلاس ElectricCar بازنویسی کنیم.

Copy Icon PYTHON
class ElectricCar(Car):
    # ... (previous code) ...

    def fill_gas_tank(self):
        """Electric cars don't have gas tanks!"""
        print("This car doesn't need a gas tank!")

اکنون، اگر متد fill_gas_tank را روی یک نمونه از ElectricCar فراخوانی کنیم، نسخه بازنویسی شده در کلاس فرزند اجرا خواهد شد.

در این درس با مفهوم قدرتمند وراثت در برنامه‌نویسی شیءگرا آشنا شدیم. دیدیم که چگونه می‌توان با ایجاد کلاس‌های فرزند، کد را به صورت منطقی سازماندهی کرده و از تکرار آن جلوگیری کرد. در درس بعدی، به بررسی «Import کردن کلاس‌ها» خواهیم پرداخت و یاد می‌گیریم که چگونه کلاس‌های خود را در ماژول‌های جداگانه ذخیره کرده و در برنامه‌های دیگر از آنها استفاده کنیم.