extension property — একটি Kotlin পদ্ধতি যা বিদ্যমান ক্লাসে নতুন প্রপার্টি যোগ করতে দেয় ইনহেরিটেন্স ছাড়া এবং সোর্স কোড পরিবর্তন না করে। extension functions-এর বিপরীতে, extension properties অবস্থা সংরক্ষণ করতে পারে না — এগুলি শুধুমাত্র getter এবং ঐচ্ছিকভাবে setter দিয়ে ঘোষণা করা হয়, কারণ এগুলোর backing field থাকে না। Kotlin Documentation, 2025 অনুযায়ী, extension properties স্ট্যাটিক getter এবং setter পদ্ধতি তে কম্পাইল হয় যেখানে receiver প্রথম প্যারামিটার হিসেবে থাকে।
মূল বিষয়
Extension property হল Kotlin-এর একটি সিনট্যাকটিক কাঠামো যা তার ঘোষণা পরিবর্তন না করেই একটি বিদ্যমান প্রকারে একটি প্রপার্টি যোগ করে। প্রপার্টিটি receiver type দিয়ে ঘোষণা করা হয় এবং এতে getter থাকতে হবে। মূল পার্থক্য সাধারণ প্রপার্টি থেকে — backing field-এর অনুপস্থিতি: extension property ডেটা সংরক্ষণ করতে পারে না, শুধুমাত্র receiver অবজেক্টের উপর ভিত্তি করে গণনা করতে পারে।
Kotlin Foundation Survey (2024) অনুযায়ী, extension properties extension functions-এর তুলনায় কম জনপ্রিয় — প্রায় 45% ডেভেলপার এগুলি নিয়মিত ব্যবহার করেন। এটি অবস্থার অভাবের সীমাবদ্ধতার কারণে, যা প্রয়োগের পরিধি সংকুচিত করে। তবে, গণনাকৃত প্রপার্টির জন্য যা যৌক্তিকভাবে একটি প্রকারের সাথে যুক্ত, extension properties সবচেয়ে সংক্ষিপ্ত বিকল্প।
Extension properties স্ট্যাটিক getter এবং setter পদ্ধতির জোড়ায় কম্পাইল হয়। বাইটকোড স্তরে, extension property এবং extension function কল করার মধ্যে কোনো পার্থক্য নেই — উভয়ই receiver প্যারামিটার সহ স্ট্যাটিক পদ্ধতি হয়ে যায়। JetBrains (Kotlin Docs, 2025) অনুযায়ী, কোনো ওভারহেড নেই।
ছোট গণনাকৃত মানের জন্য extension properties ব্যবহার করুন যা প্রপার্টির মতো দেখতে হবে, পদ্ধতি কলের মতো নয় — এটি কোড পঠনযোগ্যতা উন্নত করে এবং ইউনিফর্ম অ্যাক্সেস নীতি মেনে চলে।
Extension property ঘোষণা করতে, সাধারণ প্রপার্টির মতো সিনট্যাক্স ব্যবহার করুন, কিন্তু receiver type উপসর্গ সহ। val বাধ্যতামূলক getter সহ শুধু-পঠনযোগ্য extension property ঘোষণা করে, var getter এবং ঐচ্ছিক setter সহ পরিবর্তনযোগ্য ঘোষণা করে।
// শুধু-পঠনযোগ্য extension property
val String.isEmail: Boolean
get() = this.contains("@") && this.contains(".")
// কল
val valid = "test@test.com".isEmail
লক্ষ্য করুন: extension property বন্ধনী ছাড়া কল করা হয় — str.isEmail, str.isEmail() নয়। এটি extension property এবং extension function-এর মধ্যে মূল পার্থক্য: প্রপার্টিটি একটি ফিল্ডের মতো দেখায়, যদিও আসলে এটি getter-এর মাধ্যমে গণনা করা হয়।
Extension properties জেনেরিক হতে পারে — receiver জেনেরিক প্রকার প্যারামিটার ব্যবহার করতে পারে। এটি সার্বজনীন প্রপার্টি তৈরি করতে দেয় যা যেকোনো সংগ্রহ প্রকারের সাথে কাজ করে।
val List<T>.secondOrNull: T?
get() = if (size >= 2) this[1] else null
val items = listOf("a", "b", "c")
val second = items.secondOrNull // "b"
secondOrNull প্রপার্টি যেকোনো প্রকার T-এর জন্য কাজ করে, তালিকার দ্বিতীয় উপাদান ফেরত দেয় বা null যদি দুইটির কম উপাদান থাকে। এটি একটি সাধারণ উদাহরণ যেখানে extension property ফাংশনের চেয়ে বেশি উপযুক্ত — এর অ্যাক্সেস ফিল্ড পড়ার মতো দেখায়।
Extension property-তে backing field থাকতে পারে না কারণ এটি ক্লাস মেটাডেটাতে যোগ করা হয় না — এটি শুধুমাত্র স্ট্যাটিক getter/setter ফাংশনের জোড়া হিসাবে বিদ্যমান। Backing field (Kotlin-এ field কীওয়ার্ড) হল ক্লাসের একটি অভ্যন্তরীণ ফিল্ড যা প্রপার্টির মান সংরক্ষণ করে। Extension property-র ক্লাসের অভ্যন্তরীণ কাঠামোতে অ্যাক্সেস নেই।
// ❌ ত্রুটি: extension property-তে backing field থাকতে পারে না
var String.cachedValue: String
get() = "computed"
set(value) {
field = value // ফিল্ড অ্যাক্সেসযোগ্য নয়!
}
// ✅ সঠিক: বাহ্যিক সংরক্ষণ ব্যবহার করুন
val cache = MutableMap<String, String>()
var String.cachedValue: String
get() = cache[this] ?: ""
set(value) { cache[this] = value }
একটি বাহ্যিক Map উদাহরণে সংরক্ষণ সমস্যা সমাধান করে কিন্তু আরেকটি সমস্যা তৈরি করে — মেমরি লিক। Extension property-র মাধ্যমে প্রাপ্ত মান Map-এ চিরকাল থাকে যদি পরিষ্কার না করা হয়। এই সীমাবদ্ধতা extension properties-কে ক্যাশিং বা অস্থায়ী ডেটা সংরক্ষণের জন্য অনুপযুক্ত করে তোলে।
ক্যাশিং-এর জন্য, WeakHashMap বা স্বয়ংক্রিয় পরিষ্কারের পদ্ধতি ব্যবহার করার পরামর্শ দেওয়া হয়। JetBrains জীবনচক্র ব্যবস্থাপনা ছাড়া প্রোডাকশন কোডে বাহ্যিক সংরক্ষণ সহ var extension properties ব্যবহার এড়াতে সুপারিশ করে।
Extension property এবং extension function-এর মধ্যে পছন্দ শব্দার্থের উপর নির্ভর করে: প্রপার্টি একটি বস্তুর বৈশিষ্ট্য বর্ণনা করে, যখন ফাংশন একটি ক্রিয়া বর্ণনা করে। ইউনিফর্ম অ্যাক্সেস নীতি বলে: ক্লায়েন্টের জানা উচিত নয় যে মান গণনা করা হয়েছে নাকি সংরক্ষিত। যদি মানকে বৈশিষ্ট্য হিসাবে উপস্থাপন করা যায় (দৈর্ঘ্য, আকার, অবস্থা) — প্রপার্টি ব্যবহার করুন।
| মানদণ্ড | Extension property | Extension function |
|---|---|---|
| কল | বন্ধনী ছাড়া: obj.property | বন্ধনী সহ: obj.function() |
| শব্দার্থ | বৈশিষ্ট্য, গুণ | ক্রিয়া, অপারেশন |
| Backing field | সমর্থিত নয় | প্রযোজ্য নয় |
| প্যারামিটার | শুধুমাত্র getter/setter | যেকোনো প্যারামিটার |
| কার্যক্ষমতা | একই (স্ট্যাটিক পদ্ধতি) | একই (স্ট্যাটিক পদ্ধতি) |
| উদাহরণ | text.length | text.isEmail() |
নিয়ম সহজ: যদি অপারেশন প্যারামিটার নেয় — extension function ব্যবহার করুন। যদি এটি প্যারামিটার ছাড়া একটি সহজ গণনাকৃত মান হয় — extension property ব্যবহার করুন। Android Architecture Guide (Google, 2025) অনুযায়ী, ডেটা অ্যাক্সেসের জন্য extension properties এবং পার্শ্ব প্রতিক্রিয়া সহ অপারেশনের জন্য extension functions-কে অগ্রাধিকার দেওয়া উচিত।
var কীওয়ার্ড সহ extension property setter সমর্থন করে, কিন্তু মান সংরক্ষণের ক্ষমতা ছাড়া — setter সাধারণত একটি পার্শ্ব প্রতিক্রিয়া করে বা বাহ্যিক সংরক্ষণে ডেটা সংরক্ষণ করে। সিনট্যাক্স পরিবর্তনযোগ্য ক্লাস প্রপার্টির মতো।
// setter সহ পরিবর্তনযোগ্য extension property
var StringBuilder.lastChar: Char
get() = this[length - 1]
set(value) {
this.setCharAt(length - 1, value)
}
val sb = StringBuilder("Kotlin")
println(sb.lastChar) // n
sb.lastChar = '!'
println(sb) // Kotli!
lastChar প্রপার্টি Kotlin ডকুমেন্টেশনের একটি ক্লাসিক উদাহরণ। Getter StringBuilder-এর শেষ অক্ষর ফেরত দেয়, setter এটি একটি নতুন মান দিয়ে প্রতিস্থাপন করে। লক্ষ্য করুন: অবস্থাটি নিজেই StringBuilder-এ সংরক্ষিত (setCharAt-এর মাধ্যমে), আলাদা ফিল্ডে নয় — এটি extension property-র সঠিক ব্যবহার।
বাস্তব প্রকল্পে, extension properties প্রায়শই সংগ্রহ ডেটা অ্যাক্সেস সহজ করতে, UI উপাদানের আকার বা অবস্থা গণনা করতে এবং বিদ্যমান ক্লাসের উপরে সুবিধাজনক API তৈরি করতে ব্যবহৃত হয়। Kotlin স্ট্যান্ডার্ড লাইব্রেরি সক্রিয়ভাবে এই পদ্ধতি ব্যবহার করে: সংগ্রহের জন্য size, indices, lastIndex — এগুলি extension properties।
// সংগ্রহের জন্য extension properties
val List<Int>.sumFast: Int
get() = fold(0) { acc, i -> acc + i }
val String.half: String
get() = this.substring(0, length / 2)
// Android View-এর জন্য extension property
val View.isVisible: Boolean
get() = visibility == View.VISIBLE
// নিরাপদ receiver-এর মাধ্যমে শূন্য পরীক্ষা
val String?.isNullOrBlank: Boolean
get() = this == null || this.isBlank()
View-এর জন্য extension property isVisible — একটি উদাহরণ যা প্রতিটি Android ডেভেলপারের জানা উচিত। view.visibility == View.VISIBLE-এর পরিবর্তে আপনি view.isVisible লিখতে পারেন। এটি কেবল ছোট নয়, প্রাকৃতিক ভাষার মতো পড়া যায়: «ভিউ যদি দৃশ্যমান হয়»। সরলতা সত্ত্বেও, এই ধরনের প্রপার্টি কোড পঠনযোগ্যতা উল্লেখযোগ্যভাবে উন্নত করে।
সচরাচর জিজ্ঞাসিত প্রশ্ন
না, extension properties companion object বা object declaration-এর জন্য ঘোষণা করা যায় না। এক্সটেনশন পদ্ধতি শুধুমাত্র ক্লাস, ইন্টারফেস এবং nullable প্রকারে প্রযোজ্য। object-এর জন্য, সাধারণ শীর্ষ-স্তরের ফাংশন ব্যবহার করুন।
Inline প্রপার্টি (inline মডিফায়ার সহ) — Kotlin-এর একটি পদ্ধতি যা প্রপার্টি অবজেক্ট তৈরি না করেই getter/setter কল করে। Extension property সর্বদা স্ট্যাটিক পদ্ধতিতে কম্পাইল হয়, যখন inline প্রপার্টি র্যাপার ছাড়া কল-এ কম্পাইল হয়। এগুলি ভিন্ন সমস্যা সমাধান করে: extension property বিদ্যমান প্রকারে প্রপার্টি যোগ করে, inline — নিজস্ব প্রপার্টির কল অপ্টিমাইজ করে।
হ্যাঁ, extension property-তে অ্যানোটেশন থাকতে পারে, কিন্তু শুধুমাত্র ঘোষণা স্তরে। সাধারণ ক্লাস প্রপার্টির বিপরীতে, extension property-র getter বা setter আলাদাভাবে অ্যানোটেট করা যায় না। উদাহরণ: @JvmName("getIsValid") val String.isValid get() = true.
না, extension properties companion object-এর সাথে receiver হিসাবে ঘোষণা করা যায় না। এটি ভাষার একটি সীমাবদ্ধতা — extension property শুধুমাত্র প্রকারের ইনস্ট্যান্সের সাথে কাজ করে, যখন companion object একটি স্ট্যাটিক প্রসঙ্গ। শীর্ষ-স্তরের extension ফাংশন বা ধ্রুবক ব্যবহার করুন।
সর্বনিম্ন। প্রতিটি extension property কম্পাইল করা বাইটকোডে একটি স্ট্যাটিক getter পদ্ধতি (এবং ঐচ্ছিকভাবে setter) যোগ করে। তুলনার জন্য, একই প্রপার্টি সহ র্যাপার ক্লাস তৈরি করা একটি সম্পূর্ণ ক্লাস যোগ করে। Extension properties কার্যকারিতা বাড়ানোর একটি হালকা পদ্ধতি।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন