کاتلین از ابتدا : extension functions ( قسمت دوم )

بررسی قابلیت override کردن در extension function

شما توی کاتلین به روش عادی میتونید متدها رو override کنید، ولی یک extension function رو نمیشه override کرد.

فرض کنید که شما دو تا کلاس دارین، که یکیش کلاس View باشه که فرزندی به اسم ‌Button رو داره ، و دیگری کلاس Button هست که متد click رو از پدر خودش override میکنه و به قولی به ارث میبره .

فرض کنید یک متغییری رو از نوع View تعریف کردین، به این خاطر که Button از View ارث‌بری داره، میتونید یک متغییر از جنس Button رو داخل همون متغییر ذخیره کنید، خب حالا اگه یک متدی مثل click رو داخل همین متغییر فراخوانی کنید که داخل کلاس button ،ه override بشه. نتیجه‌ای شبیه پایینی دارین :

https://gist.github.com/sajjadyousefnia/1674e86ee40710d4f5e48a462461639c

ولی خلاف انتظار ما این extension ای که بالا نوشته شده، کار نمیکنه.

دلیلش اینه که در حقیقت extension functionها بخشی از کلاس نیستن، و به صورت اکسترنال و مجازی به کلاس‌ها نسبت داده میشن.

درسته که میشه extension function هایی رو با نام و پارامترهای یکسان ، چه برای کلاس پدر و چه کلاس فرزند تعریف کرد، ولی موقعی که بخوایم extendion functionای رو فراخوانی کنیم، تابعی برای ما فراخوانی میشه که همون اول ( به صورت تابع استاتیک ) تعریف شده، نه اون کلاسی که موقع اجرا به متغییر نسبت داده میشه.

خب حالا با یک مثال مساله رو براتون بیشتر باز میکنم. اول به شکل پایینی نگاه کنید‌ :

ه Extension functionهایی که خارج از کلاس تعریف شدن
ه Extension functionهایی که خارج از کلاس تعریف شدن


مثال پایینی extension functionای به نام showOff رو که داخل کلاس View و Button تعریف شده رو نشون میده.

https://gist.github.com/sajjadyousefnia/dac7530fadd0c1697ee6569f38627973

با اینکه این متغییر از جنس Button هست، ولی همونطور که میبینید وقتی که متد showOff رو با استفاده از یک متغییری که از نوع View هست، فراخوانی میکنید، extension functionای که متناظر با اون هست، فراخوانی میشه.

پس هدف اصلیم از گفتن این قسمت دو چیز مهم هست، که دومی خودش نتیجه‌ی قسمت اوله :

1- یکی اینکه وقتی از کلاسی ارث‌بری داریم، extension function های کلاس پدر به کلاس فرزند به ارث نمیرسه.

2- و دیگری اینکه فرض کنید یک کلاسی داریم که یک extension function و یک member function با اسم و پارامترهای یکسان دارن ، توی فراخوانی اولویت با member fucntion هست. باید همیشه موقع ارث‌بری از یادتون باشه که اگه ما مثلا یک کلاس A داشته باشیم و یک کلاس B رو بسازیم که از کلاس A ارث ببره و بعدش توی کلاس B ، ما یک member functionای رو بسازیم که دارای اسم و پارامترهای یکسان با یکی از extension function های پدر داشته باشه، در این صورت تقدم و اولویت با member function خواهد بود.

بحث ما توی این قسمت در مورد به وجود آوردن توابع اضافی برای کلاس‌های خارجی بود. حالا ببینیم که همون کار رو چجوری میشه برای propertyها انجام داد در قسمت بعد.