آموزش Extension functions در کاتلین
سلام دوستان همیشگی در این سری از آموزش برنامه نویسی اندروید به آموزش Extension functions در کاتلین می پردازیم شاید یکی از ویژگی که بیشتر برنامه نویسان جاوا را وسوسه می کند تا از کاتلین استفاده کنند همین Extension functions هاست که در ادامه Extension functions ها را بیشتر توضیح خواهیم داد با ما همراه باشید.
مطمئنن سوال اول شما اینکه
Extension functions چیست ؟
به زبان ساده Extension functions این قابلیت را به شما می دهند تا بدون اینکه در فانکشن یک کلاس دستکاری انجام دهید چیزی به آن اضافه کنید ! این ویژگی انقدر خوب هست که شما کلی کار می توانید باهاش انجام بدید مثلا یک متد دارید 10 تا ورودی دارد (هرچند که داشتن همچین متدی خیلی اشتباه هست متد نباید بیشتر از 3 ورودی داشته باشد) و فقط لازم دارید که یک ورودی به آن ارسال کنید به صورت پیشفرض توی جاوا شما باید بیایید و Constructor جدید براش بسازید ولی اینجا دیگه نیاز نیست و فقط یک ورودی به متدی که مثلا ده ورودی دارد ارسال می کنید.
مطمئنن سوال دوم شما اینکه چه جوری ازش استفاده کنیم ؟
نحوه استفاده از Extension functions در کاتلین
چندتا مثال ساده می زنم تا بعدا بتوانید در پروژه های خودتان پیشرفتش رو به کار ببرید 🙂
مطمئنن همه با دستور Toast آشنا هستید
1 | Toast.makeText(this@MainActivity, message, Toast.LENGTH_SHORT).show() |
اگر بخوایم Extension functions را در Toast پیاده سازی کنیم همچین چیزی اتفاق می افتد
1 2 3 | fun Context.toast(message: String){ Toast.makeText(this, message, Toast.LENGHT_SHORT).show() } |
بزارید یک مثال کاربردی تر بزنیم فکر کنید می خوایم با استفاده از کتابخانه picasso عکسی رو لود کنیم به صورت پیشفرض که از کد زیر استفاده می کنیم.
1 | Picasso.with(imageView.context).load(url).into(imageView) |
حالا فرض کنید چقدر بهتر می شد که اگر خود Imageview یک متد به نام Load داشت و ما فقط بهش ورودی یا Url عکس رو می دادیم و عکس لود می شد خب با کاتلین این کار امکان پذیره کد زیر را ببینید.
1 2 3 | fun ImageView.loadUrl(url: String) { Picasso.with(context).load(url).into(this) } |
در واقع در بالا اومدیم و یک متد جدید به ImageView اضافه کردیم و نحوه استفاه از آن هم همانند زیر است.
1 | imageView.loadUrl(url) |
بدون اینکه کلاس خاصی بسازید این کار انجام شده که واقعا فوق العاده است.
در واقع در Body متد خود کاری که می خواهید انجام شود را قرار میدهید و در بخش متدی که میسازید یک فانکشن برای شئی یا کلاس تعریف می کنید.
کد زیر در واقع نوع تعریف این نوع فانکشن هست
1 | fun <class_name>.<method_name>() |
کلاس زیر هم برای تکمیل مثال ها هست
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Student{ fun isPassed(mark: Int): Boolean{ return mark>40 } } fun Student.isExcellent(mark: Int): Boolean{ return mark > 90 } fun main(args: Array<String>){ val student = Student() val passingStatus = student.isPassed(55) println("student passing status is $passingStatus") val excellentStatus = student.isExcellent(95) println("student excellent status is $excellentStatus") } |
سخن آخر هم اینکه از این ویژگی بیشتر در کتابخانه ها می توانید استفاده کنید در واقع بدون دسترسی داشتن به سورس کد آن کتابخانه می توانید متد های جدید خودتان را به آن اضافه کنید یه جورایی مثل تغییر در متد می ماند ولی متد اصلی تغییر نمی کند بلکه ویژگی های متد یا کلاس رو ارث بری می کند به همین راحتی 🙂
موفق و پیروز باشید.