تعریف Extension در کاتلین
در این مطلب فرض شده با شی گرایی و توابع (متدها) در کاتلین آشنایی دارید. اگه با توابع در کاتلین اشنایی ندارید میتونید به مطلب بررسی توابع در کاتلین مراجعه کنید.
اکستنشن ها در کاتلین توابع و متغیر هایی هستن که برای کلاس تعریفشون میکنیم.
اکستنشن ها تغییری در داخل کلاس ایجاد نمیکنن و مانند پراپرتی (field) و تابع (function) های عضو کلاس اونا رو صدا میزنیم.
با اینکه اکستنشن ها مانند اعضای کلاس صدا زده میشن اما عضوی به کلاس اضافه نمیکنن و استاتیک در نظر گرفته میشن. مثلا اگه برای دو کلاس تابع اکستنشن یکسان تعریف کرده باشیم، و دو کلاس از همدیگ ارث ببرن بدون توجه به وراثت؛ زمان کامپایل مشخص میشه تابع اکستنشن کدوم کلاس اجرا میشه.
معمولا اکستنشن ها رو داخل فایل کاتلین؛ یعنی به صورت Top Level تعریف میکنیم.
اکستنشن ها شامل توابع اکستنشن، اکستنشن پراپرتی (Extension Property)، و اکستنشن های Companion Object هستند.
تابع اکستنشن
به توابعی گفته میشه که برای یک کلاس، در خارج از کلاس تعریف میکنیم.
فرم کلی:
در اینجا MyClass اسم کلاس مورد نظر است یه نقطه میزاریم سپس اسم دلخواه برای تابعمون مینویسیم و مثل توابع معمولی پارامتر های دلخواه داخل پرانتز تابع رو تعریف میکنیم.
همینطور اگه برای کلاس Generic تعریف شده بود مانند بالا میتونیم برای تابعی که تعریف میکنیم Generic تعریف کنیم تا برای هر نوع متغیری قابل استفاده باشه
توابع اکستنشن رو مثل توابع عضو کلاس (ممبر فانکشن ها) صدا میزنیم.
نکته:
اگه تابع اکستنشن با یکی از توابع داخل کلاس از نظر پارامتر و اسم یکی باشه هنگام صدا زدن، تابع داخل کلاس به اجرا در میاد.
مثال:
یک function به کلاس String اضافه کردیم که بررسی میکنه یک String متقارن است یا خیر
مثال:
اجرای تابع اکستنشن از دو کلاس پدر و فرزند.
همینطور که در ابتدا گفتیم اکستنشن ها استاتیک در نظر گرفته میشن و زمان کامپایل مشخص میشه تابع کدوم کلاس اجرا بشه در بالا نتیجه اجرای تابع printInfo مربوط به A است. چون پارامتر show از نوع A است.
استفاده از کلیدواژه ی this داخل تابع:
داخل تابع اکستنشن با کلید واژه ی this میتونیم به نمونه کلاس و اعضای کلاس دسترسی داشته باشیم.
مثال:
تابع swap رو برای MutableList هایی از نوع Int تعریف میکنیم.
این تابع برای هر MutableList که نوعش Int باشه قابل استفاده است.
صدا زدن تابع:
تعریف تابع اکستنشن به صورت Generic:
میتونیم توابع اکستنشن رو به صورت، جنریک تعریف کنیم.
مثال:
در زیر تابع swap رو به صورت جنریک تعریف کردیم تا برای هر نوعی قابل استفاده باشه.
اکستنشن پراپرتی در کاتلین
فرم کلی:
کاملا شبیه extension function هاست
اکستنشن پروپرتی ها نمیتونن دارای مقدار اولیه باشن.
همونطور که گفتیم extension ها ربطی به کلاس ندارن پس مقدار اولیه ای برای extension property ها وجود نداره
مثال:
در بالا یک property به کلاس Int اضافه کردیم که بررسی میکنه عدد زوجه یا نه.
اکستنشن های Companion Object
اگه برای یک کلاس Companion Object تعریف شده باشه، میتونیم برای Companion Object اکستنشن فانکشن و اکستنشن پراپرتی تعریف کنیم.
برای صدا زدنش مثل بقیه اعضای داخل companion object عمل میکنیم:
تعریف اکستنشن به عنوان عضو یک کلاس
توجه:
برای مطالعه ی این بخش توصیه میشه با مبانی شی گرایی اشنایی داشته باشید.
میتونیم برای یک کلاس داخل کلاس دیگه اکستنشن تعریف کنیم به کلاسی که داخلش اکستنشن تعریف کردیم dispatch receiver و به کلاسی که اکستنشن رو براش تعریف کردیم extension receiver میگیم.
مثال:
استفاده از یک کلاس به عنوان extension receiver.
استفاده از یک کلاس به عنوان dispatch receiver.
توجه:
اگه بخوایم داخل تابع printInfo یکی از اعضای dispatch receiver رو صدا بزنیم و با عضو extension receiver هم نام باشه، اولویت با اعضای extension receiver است. برای همین موقع صدا زدن اعضای dispatch receiver از this@ClassName استفاده میکنیم تا از تداخل اسمی جلوگیری بشه.
فرض کنید در کلاس MyDispatchReceiver عضوی با اسم id نیز وجود داشته باشه:
میتونیم تابع اکستنشن داخل کلاس رو به صورت open تعریف کنیم تا در وراثت بتونیم override کنیم.
توجه:
تابع اکستنشن برای extension receiver و فرزندانش استاتیک و برای dispatcher receiver عضو به حساب میاد.مثال:
ابتدا برای کلاس های A و ChildA تابع اکستنشن printInfo رو در B تعریف کردیم، سپس با ارث بری ChildB از B این دو تابع رو در ChildB بازنویسی کردیم، سپس در تابع main، تابع call رو صدا کردیم و نمونه جدید از A و ChildA رو به call پاس دادیم. چون پارامتر تعریف شده در call از نوع A است، تابع printInfo برای A در B و ChildB اجرا میشه.
خلاصه
-در کاتلین Extension ها تاثیری روی کلاس ندارن وقتی برای یک کلاس extension تعریف میکنیم فقط بیان میکنیم که function یا property تعریف شده رو باید با استفاده از متغیر کلاس صدا بزنیم.
-برای صدا زدن extension ها مانند اعضای داخل کلاس باید اسم متغیر کلاس نقطه و اسم function یا property تعریف شده رو بنویسیم.
در قطعه کد زیر به طور خلاصه از هر سه نوع یک نمونه بیان شده است:
در این مطلب به بررسی اکستنشن ها در کاتلین پرداختیم و با توابع اکستنشن ، اکستنشن پراپرتی و اکستنشن های companion object اشنا شدیم و اکستنشن های عضو کلاس رو بررسی کردیم.
موفق باشید