میدونیم که سازنده ها در پیاتون با تابع جادویی ( magic methods )
__init()__
پیاده سازی میشن ٬ با فرض اینکه با کلاس ها و سازنده هاش و مفهوم وراثت یه آشنایی نسبی دارید با یه مثال ساده بحثو شروع میکنیم :
در مثال بالا یک کلاس مستطیل تعریف کردیم، توی سازنده یا همون constructor کلاس طول و عرض رو گرفتیم و این طول و عرض رو به attribute های شی این کلاس نسبت دادیم . در ادامه دو تابع برای محاسبه ی مساحت و محیط این مستطیل پیاده سازی کردیم که تابع area طول رو ضرب در عرض میکنه و تابع surface مجموع طول ضرب در 2 ، با عرض ضرب در 2 ( محیط مستطیل ) بدست میاره
تا اینجا عملکرد تابع __init__() مشخص و واضحه اما اگر دو یا بیشتر کلاس داشته باشیم که از همدیگه ارث بری کرده باشن اونوقت توابع سازنده چگونه کار میکنند ؟ این مثال رو ببینید :
اگر کد بالارو اجر کنیم با ارور
'Square' object has no attribute 'width' روبرو میشیم
چرا ؟؟؟ الان میگم
به این دلیل که متد area که تو کلاس مستطیل نوشیتم از دو property طول و عرض استفاده میکنه برای محاسبه ی مساحت و این طول و عرض در متد سازنده ی کلاس مستطیل دریافت میشن ولی وقتی ما شی sqr1 رو تعریف کردیم فقط متد سازنده ی کلاس مربع فراخوانی شد ... ولی متد سازنده ی کلاس مستطیل صدا زده نشد ! چونکه متد سازنده ی کلاس بالا ( مستطیل ) صدا زده نشد -- > پس از تابع هایی که وابسته به سازنده هستن نمیشه استفاده کرد . اما راه حل چیه ؟ استفاده از موجودی به اسم super()
حالا کد بالارو بازنویسی میکنیم :
حالا متد بالا کار میکنه، چون که در سازنده ی کلاس مربع ، سازنده ی کلاس مستطیل رو هم فراخوانی کردیم
def __init__(self, length):
super().__init__(length , length)
با کمک تابع super که بحث امروز ماست ! تونستیم به اعضای کلاس مادر ( یعنی کلاس مستطیل ) دسترسی داشته باشیم . دقیقا کاربرد تابع super () اینجاست : به کمک این تابع میتونیم به اعضای کلاس مادر دسترسی داشته باشیم : یعنی اگر یک کلاس A داشته باشیم و یک کلاس B که از A ارث بری میکنه حالا اگر بخوایم توی تابع B اعضای کلاس A رو صدا بزنیم از super استفاده میکنیم . در واقع super به ما دسترسی به یک کلاس بالاتر رو میده . اصل ماجرا اینه که تابع سوپر یک شی موقت ، از کلاس بالاتر رو برمیگردونه ، پس ما به کمک اون شی میتونیم به اعضای کلاس مادر درسترسی داشته باشیم .
در مثال بالا ما با کمک super سازنده ی کلاس مستطیل ( کلاس مادر ) رو صدا زدیم ، حالا میخوایم یک متد کلاس مادر رو صدا بزنیم ( برای اینکه نشون بدیم ، با استفاده از super نه فقط به سازنده ی کلاس مادر بلکه به همه ی اعضای اون کلاس دقیقا مثل یک شئ از کلاس مادر دسترسی خواهیم داشت ) :
میبینید که در خط 5 این مثال با استفاده از super تابع area رو هم که در کلاس مستطیل هست صدا زدیم ، اینجوری باعث میشه که از تکرار کد جلوگیری کنیم ، یعنی اگر مثلا یک تابع در کلاس مادر داشتیم که میخواستیم در کلاس بچه ( کلاسی که از کلاس مادر ارث میبره ) پیاده سازی کنیم ، نیازی نیست دو بار در هردو کلاس بنویسیمش و اینجوری حجم کد کمتر و clean تر میشه
لپ کلام اینکه تابع super یک شی موقت از کلاس بالاتر به ما برمیگردونه و بنابراین ما میتونیم به اعضای کلاس بالاتر دسترسی داشته باشیم . تابع super بیشتر در وراثت به کار ما میاد و باعث میشه که دیگه لازم نباشه کد هارو تکرار کنیم .