extension function — Kotlin کا ایک طریقہ کار جو موجودہ کلاسز میں وراثت کے بغیر اور سورس کوڈ میں تبدیلی کیے بغیر نئے میتھڈ شامل کرنے کی اجازت دیتا ہے۔ فنکشن ایک وصول کنندہ قسم کے سابقہ کے ساتھ اعلان کیا جاتا ہے اور اس قسم کے عام میتھڈ کی طرح بلایا جاتا ہے۔ Kotlin Documentation, 2025 کے مطابق، extension functions وصول کنندہ کو پہلے پیرامیٹر کے طور پر لے کر جامد میتھڈز میں مرتب ہوتے ہیں، جو عام کالز کے مقابلے میں رن ٹائم پر صفر اوور ہیڈ کی ضمانت دیتا ہے۔
اہم نکات
Extension function ایک فنکشن ہے جو کلاس کے باہر اعلان کیا جاتا ہے لیکن اس کے میتھڈ کے طور پر بلایا جاتا ہے۔ یہ ایک وصول کنندہ قسم لیتا ہے جس میں نیا میتھڈ شامل کیا جاتا ہے۔ فنکشن کے اندر، کلیدی لفظ this وصول کنندہ قسم کی مثال کی طرف اشارہ کرتا ہے۔ یہ طریقہ فائنل کلاسز، تیسرے فریق کی لائبریری کلاسز اور حتیٰ کہ ابتدائی اقسام کو بھی ریپر بنائے بغیر توسیع دینے کی اجازت دیتا ہے۔
Java کے برعکس، جہاں موجودہ کلاس میں میتھڈ شامل کرنے کے لیے وراثت یا جامد یوٹیلیٹی کلاس کی ضرورت ہوتی ہے، Kotlin بغیر boilerplate کے ایک خوبصورت حل فراہم کرتا ہے۔ Kotlin Foundation تحقیق (2024) کے مطابق، extension functions زبان کی پانچ سب سے زیادہ استعمال ہونے والی خصوصیات میں شامل ہیں — 78% Kotlin ڈویلپر انہیں روزمرہ کے کام میں استعمال کرتے ہیں۔
Kotlin کمپائلر extension function کو ایک جامد میتھڈ میں ترجمہ کرتا ہے جہاں وصول کنندہ کی مثال پہلی دلیل کے طور پر منتقل کی جاتی ہے۔ اس کا مطلب ہے کہ extension functions ہدف کلاس کے بائٹ کوڈ کو تبدیل نہیں کرتے اور encapsulation نہیں توڑتے — صرف وصول کنندہ کے عوامی فیلڈز اور میتھڈز تک رسائی ممکن ہے۔
صاف یوٹیلیٹی فنکشنز لکھنے کے لیے extension functions استعمال کریں جو منطقی طور پر کسی مخصوص قسم سے منسلک ہوں لیکن اس کے سورس کوڈ میں شامل نہ کیے جا سکتے ہوں۔
Extension function کا بنیادی نحو: وصول کنندہ قسم کا نام، ایک ڈاٹ، فنکشن کا نام، پھر پیرامیٹرز اور واپسی کی قسم۔ فنکشن کے اندر، وصول کنندہ this کے ذریعے قابل رسائی ہے۔
// Extension function for String
fun String.isEmail(): Boolean {
return this.contains("@") && this.contains(".")
}
// Called as regular String method
val result = "user@example.com".isEmail() // true
اس مثال میں، isEmail() تمام سٹرنگز کے لیے دستیاب ہو جاتا ہے۔ فنکشن کے اندر، this اس سٹرنگ کی طرف اشارہ کرتا ہے جس پر میتھڈ بلایا گیا ہے۔ Kotlin زیادہ تر معاملات میں this کو چھوڑنے کی اجازت دیتا ہے — آپ this.contains("@") کے بجائے صرف contains("@") لکھ سکتے ہیں۔
Extension functions اضافی پیرامیٹرز قبول کر سکتے ہیں اور کسی بھی قسم کی قدر واپس کر سکتے ہیں۔ یہ انہیں مکمل فنکشن بناتا ہے، نہ کہ صرف نحوی شکر۔
fun List<Int>.defaultIfEmpty(default: Int): List<Int> {
if (this.isEmpty()) return listOf(default)
return this
}
val populated = listOf(1, 2).defaultIfEmpty(0)
val empty = listOf<Int>().defaultIfEmpty(0)
default پیرامیٹر خالی فہرست کے لیے واپس کردہ قدر کی وضاحت کرتا ہے۔ Extension function generic ہو سکتا ہے — List
Kotlin میں extension functions جامد تقسیم استعمال کرتے ہیں، مجازی تقسیم نہیں۔ یہ عام کلاس میتھڈز سے ایک اہم فرق ہے۔ کون سا extension function بلایا جائے گا یہ رن ٹائم کی اصل قسم کے بجائے متغیر کی جامد قسم کے ذریعے مرتب وقت پر طے کیا جاتا ہے۔
open class Animal
class Dog : Animal()
fun Animal.speak() = "Animal sound"
fun Dog.speak() = "Woof"
fun test() {
val animal: Animal = Dog()
println(animal.speak()) // "Animal sound" — static type Animal
val dog: Dog = Dog()
println(dog.speak()) // "Woof" — static type Dog
}
اگرچہ animal متغیر Dog کی مثال کی طرف اشارہ کرتا ہے، Animal کے لیے extension function بلایا جاتا ہے کیونکہ متغیر کی جامد قسم Animal ہے۔ اگر speak() ایک مجازی کلاس میتھڈ ہوتا، تو Dog.speak() بلایا جاتا۔ یہ رویہ extension functions کے ساتھ API ڈیزائن کرتے وقت غور کرنا ضروری ہے۔
Extension functions کلاس کے ممبر نہیں ہیں — یہ عام فنکشن ہیں جنہیں دوسری فائل میں استعمال کرنے کے لیے درآمد کی ضرورت ہوتی ہے۔ Kotlin درآمد کے دو اختیارات فراہم کرتا ہے: فنکشن کے نام کے مطابق یا نام تبدیل کرکے۔
// Import by name
import com.example.extensions.isEmail
// Import with alias (to resolve conflicts)
import com.example.extensions.isEmail as isValidEmail
// Call after import
val valid = "test@test.com".isEmail()
as کے ذریعے نام تبدیل کرنا نام کے تضاد کی صورتوں میں مفید ہے — مثال کے طور پر، اگر دو لائبریریاں ایک ہی قسم کے لیے ایک ہی نام کا extension function فراہم کریں۔ اس صورت میں، آپ ان میں سے ایک کو مختلف نام سے درآمد کر سکتے ہیں اور نئے نام کا استعمال کرتے ہوئے کال کر سکتے ہیں۔
Extension functions مختلف سطحوں پر اعلان کیے جا سکتے ہیں:
| سطح | نمائیت | مثال |
|---|---|---|
| Top-level | درآمد کے بعد پورا پروجیکٹ | fun String.isEmail() |
| Member extension | مالک کلاس کے اندر | class A { fun B.ext() } |
| Local | ایک فنکشن کے اندر | fun test() { fun String.ext() } |
Member extension functions ایک خاص صورت ہے جہاں extension function کسی دوسری کلاس کے اندر اعلان کیا جاتا ہے۔ اس صورت میں، extension function کے اندر وصول کنندہ (فنکشن کا this) اور بیرونی کلاس کے ممبر دونوں قابل رسائی ہیں۔
اگر کسی کلاس میں extension function جیسے ہی دستخط والا میتھڈ ہے، تو کلاس ممبر ہمیشہ بلایا جاتا ہے۔ Extension function کبھی کلاس میتھڈ کو اوور رائڈ نہیں کرتا — یہ حادثاتی اوور رائڈ کو روکنے کے لیے ایک معماری فیصلہ ہے۔
class User {
fun greet() = "Hello from class"
}
fun User.greet() = "Hello from extension"
fun main() {
val user = User()
println(user.greet()) // "Hello from class"
}
یہاں تک کہ اگر extension function بعد میں تعریف کیا گیا ہو اور ایک ہی دستخط رکھتا ہو، کمپائلر کلاس میتھڈ کا انتخاب کرے گا۔ Kotlin کمپائلر اس صورت حال کا پتہ چلنے پر ایک انتباہ جاری کرتا ہے۔ کلاس میتھڈ موجود ہونے پر extension function کو کال کرنے کا واحد طریقہ اسے عام فنکشن کے طور پر کال کرنا ہے: greet(user)۔
Android ڈیولپمنٹ میں، extension functions View، Context اور fragments کے ساتھ کام کرنے کے لیے ایک معیاری ٹول بن چکے ہیں۔ Android KTX لائبریری extension functions پر بنائی گئی ہے، جو Android API پر آسان ریپر فراہم کرتی ہے۔
// Extension function for working with View
fun View.show() {
visibility = View.VISIBLE
}
fun View.hide() {
visibility = View.GONE
}
// Extension function for Context — toast
fun Context.toast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
// Extension function as DSL builder
fun String.colorFormat(color: String): String =
"$color$this\u001b[0m"
toast() extension function Context پر منحصر کالوں کو مختصر بناتا ہے: Toast.makeText(context, message, length).show() لکھنے کے بجائے، صرف context.toast("متن") لکھنا کافی ہے۔ یہ boilerplate کو کم کرتا ہے اور کوڈ کو مزید پڑھنے کے قابل بناتا ہے۔
اکثر پوچھے گئے سوالات
نہیں، extension functions جامد تقسیم استعمال کرتے ہیں۔ اگر آپ بیس کلاس اور ذیلی کلاس کے لیے ایک ہی extension function کا اعلان کرتے ہیں، تو کون سا بلایا جائے گا اس کا تعین اصل رن ٹائم قسم کے بجائے مرتب وقت پر متغیر کی جامد قسم سے ہوتا ہے۔
آپ nullable وصول کنندہ اقسام کے لیے extension functions کا اعلان کر سکتے ہیں: fun String?.isNullOrEmail()۔ ایسے فنکشن کے اندر، this null ہو سکتا ہے، اس لیے آپ کو محفوظ کال آپریٹرز یا واضح null جانچ استعمال کرنی چاہیے۔
نہیں، extension functions جامد میتھڈز میں مرتب ہوتے ہیں۔ بائٹ کوڈ کی سطح پر، extension function کو کال کرنا وصول کنندہ کو پہلے پیرامیٹر کے طور پر لے کر جامد میتھڈ کو کال کرنے کے برابر ہے۔ کوئی عکاسی یا متحرک تقسیم شامل نہیں ہے۔
ہاں، extension properties extension functions کی طرح کام کرتی ہیں لیکن حالت ذخیرہ نہیں کر سکتیں — صرف getter اور setter۔ مثال کے طور پر: val List
Java میں آپ StringUtils.isEmail(str) لکھتے ہیں، جبکہ Kotlin میں آپ str.isEmail() لکھتے ہیں۔ فرق صرف نحو کا نہیں ہے: extension functions IDE میں خودکار تکمیل کی حمایت کرتے ہیں، کال چینز کی پڑھنے کی اہلیت کو بہتر بناتے ہیں، اور IDE کو کسی مخصوص قسم کے لیے متعلقہ فنکشنز تجویز کرنے کی اجازت دیتے ہیں۔ Java میں یہ صلاحیتیں نہیں ہیں۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں