Kotlin হল একটি প্রোগ্রামিং ভাষা যা সারা বিশ্বের Android ডেভেলপাররা ব্যাপকভাবে ব্যবহার করেন। এই বিষয় আপনাকে Kotlin-এর ক্র্যাশ কোর্স প্রদান করে যাতে আপনি দ্রুত কাজ শুরু করতে পারেন।
ভেরিয়েবল ঘোষণা
ভেরিয়েবল ঘোষণা করার জন্য Kotlin দুটি আলাদা কীওয়ার্ড ব্যবহার করে: val ও var।
- যে ভেরিয়েবলের ভ্যালু কখনও পরিবর্তন হয় না তার জন্য
valব্যবহার করুন।valব্যবহার করে ঘোষণা করা হয়েছে এমন কোনও ভেরিয়েবলে আপনি কোনও ভ্যালু আবার অ্যাসাইন করতে পারবেন না। - যে ভেরিয়েবলের ভ্যালু পরিবর্তন হতে পারে তার জন্য
varব্যবহার করুন।
নিচের উদাহরণে, count হল Int ধরনের একটি ভেরিয়েবল, যাকে 10-এর
প্রাথমিক মান অ্যাসাইন করা হয়েছে:
var count: Int = 10
Int হল এমন একটি ধরন যা একটি পূর্ণসংখ্যাকে বোঝায়, এটি হল অসংখ্য সংখ্যাসূচক ধরনের মধ্যে একটি যা
Kotlin-এ উপস্থাপন করা যেতে পারে। অন্যান্য ভাষার মতো, আপনার সংখ্যাসূচক ডেটার উপর নির্ভর করে আপনি
Byte, Short, Long, Float এবং Double-ও ব্যবহার করতে পারবেন।
var কীওয়ার্ডের অর্থ হল, প্রয়োজন অনুযায়ী আপনি count-এ ভ্যালু আবার অ্যাসাইন করতে পারবেন। যেমন, আপনি count-এর ভ্যালু 10 থেকে 15-এ পরিবর্তন করতে পারেন:
var count: Int = 10
count = 15
তবে, কিছু ভ্যালু পরিবর্তন করার জন্য নয়। String-এর কথা বিবেচনা করুন, যাকে
languageName বলা হয়। আপনি যদি নিশ্চিত করতে চান যে languageName সবসময় "Kotlin" ভ্যালু
হোল্ড করে, তাহলে আপনি val কীওয়ার্ড ব্যবহার করে languageName ঘোষণা করতে পারেন:
val languageName: String = "Kotlin"
কী পরিবর্তন করা যাবে সেই বিষয়ে এই কীওয়ার্ডগুলি আপনাকে স্পষ্ট ধারণা দেয়। প্রয়োজন অনুযায়ী
নিজের সুবিধা মতো ব্যবহার করুন। কোনও ভেরিয়েবল রেফারেন্সকে আবার অ্যাসাইন করা গেলে, তাহলে
সেটিকে var হিসেবে ঘোষণা করুন। অন্যথায়, val ব্যবহার করুন।
টাইপ ইনফারেন্স
আগের উদাহরণটি চালিয়ে গেলে, আপনি যখন
languageName-এ প্রাথমিক ভ্যালু অ্যাসাইন করেন, তখন Kotlin কম্পাইলার অ্যাসাইন করা ভ্যালুর
টাইপের উপর ভিত্তি করে টাইপ অনুমান করতে পারে।
"Kotlin"-এর ভ্যালু String টাইপের হওয়ায়, কম্পাইলার অনুমান করে যে
languageName-ও একটি String। মনে রাখবেন, Kotlin হল একটি স্ট্যাটিক-টাইপ
ভাষা। এর অর্থ হল, কম্পাইল করার সময় ধরনটি সমাধান করা হয় এবং সেটি কখনও
পরিবর্তিত হয় না।
নিচের উদাহরণে, languageName-কে String হিসেবে অনুমান করা হয়েছে, তাই আপনি String ক্লাসের অংশ নয় এমন কোনও ফাংশন
কল করতে পারবেন না:
val languageName = "Kotlin"
val upperCaseName = languageName.toUpperCase()
// Fails to compile
languageName.inc()
toUpperCase() হল এমন একটি ফাংশন যা শুধুমাত্র
String ধরনের ভেরিয়েবেলে কল করা যায়। কারণ Kotlin কম্পাইলার languageName-কে String হিসেবে অনুমান করেছে,
আপনি নিরাপদে toUpperCase() কল করতে পারবেন। inc() হল একটি Int অপারেটর
ফাংশন, তাই এটি String-এ কল করা যায় না। টাইপ
ইনফারেন্সের ক্ষেত্রে Kotlin-এর দৃষ্টিভঙ্গি আপনাকে সংক্ষিপ্ততা ও টাইপ-সেফটি, দুটিই প্রদান করে।
নাল সেফটি
কিছু ভাষায়, প্রাথমিক স্পষ্ট মান না দিয়েই রেফারেন্স টাইপ ভেরিয়েবল ঘোষণা করা যায়। এইসব ক্ষেত্রে, ভেরিয়েবলে সাধারণত শূন্য মান থাকে। Kotlin ভেরিয়েবল ডিফল্ট হিসেবে শূন্য মান রাখতে পারে না। এর অর্থ হল, নিচের স্নিপেটটি সঠিক নয়:
// Fails to compile
val languageName: String = null
কোনও ভেরিয়েবেলে শূন্য মান রাখতে হলে, সেটিকে নালযোগ্য ধরনের হতে হবে। আপনি
? দিয়ে ভেরিয়েবলের ধরন শেষ করে, সেটিকে নাল হতে পারে বলে নির্দিষ্ট করতে পারেন, যেমন
নিচের উদাহরণে দেখানো হয়েছে:
val languageName: String? = null
String? ধরনের সাথে, আপনি String ভ্যালু বা null অ্যাসাইন করতে পারেন
languageName।
আপনাকে অবশ্যই নাল ভেরিয়েবল সাবধানে হ্যান্ডেল করতে হবে, তা না হলে একটি ভয়াবহ
NullPointerException হওয়ার ঝুঁকি থাকে। যেমন, Java-তে, আপনি যদি কোনও নাল ভ্যালুতে
কোনও মেথড ইনভোক করার চেষ্টা করেন, তাহলে আপনার প্রোগ্রাম ক্র্যাশ করে।
নাল মান গ্রহণ করতে পারে এমন ভেরিয়েবল নিয়ে নিরাপদে কাজ করার জন্য Kotlin একাধিক মেকানিজম প্রদান করে। আরও তথ্যের জন্য, Android-এ সাধারণ Kotlin প্যাটার্ন: নাল হওয়া যায় কিনা দেখুন।
শর্তসাপেক্ষ বাক্য
কন্ডিশনাল লজিক প্রয়োগ করার জন্য Kotlin-এ বিভিন্ন মেকানিজম আছে। এগুলির মধ্যে সবচেয়ে
সাধারণ হল if-else স্টেটমেন্ট। if কীওয়ার্ডের ঠিক পাশে প্যারেন্থেসিসের মধ্যে থাকা
কোনও এক্সপ্রেশনের মূল্যায়ন করে true পাওয়া গেলে, সেই ব্রাঞ্চের
মধ্যে থাকা কোড (অর্থাৎ, কার্লি ব্রেসেসের মধ্যে থাকা
ঠিক পরের কোড) এক্সিকিউট করা হয়। অন্যথায়, else ব্রাঞ্চের মধ্যে থাকা কোড এক্সিকিউট করা হয়।
if (count == 42) {
println("I have the answer.")
} else {
println("The answer eludes me.")
}
আপনি else if ব্যবহার করে একাধিক শর্ত দেখাতে পারবেন। এর ফলে আপনি
নিচের উদাহরণে দেখানো
মতো একটি কন্ডিশনাল স্টেটমেন্টের মধ্যে আরও গ্র্যানুলার, জটিল লজিক দেখাতে পারবেন:
if (count == 42) {
println("I have the answer.")
} else if (count > 35) {
println("The answer is close.")
} else {
println("The answer eludes me.")
}
স্টেটফুল লজিক দেখানোর জন্য কন্ডিশনাল স্টেটমেন্ট কাজে লাগে, কিন্তু আপনি
দেখতে পেতে পারেন যে সেগুলি লেখার সময় একই কথা বারবার বলতে হচ্ছে। উপরের উদাহরণে, আপনি
প্রতিটি ব্রাঞ্চে একটি করে String প্রিন্ট করেছেন। এই পুনরাবৃত্তি এড়াতে, Kotlin
শর্তসাপেক্ষ এক্সপ্রেশন অফার করে। শেষের উদাহরণটি এইভাবেও লেখা যেতে পারে:
val answerString: String = if (count == 42) {
"I have the answer."
} else if (count > 35) {
"The answer is close."
} else {
"The answer eludes me."
}
println(answerString)
পরোক্ষভাবে, প্রতিটি কন্ডিশনাল ব্রাঞ্চের শেষ লাইনে এক্সপ্রেশনের ফলাফল রিটার্ন করা হয়, তাই আপনাকে return কীওয়ার্ড ব্যবহার করতে হবে না।
কারণ, তিনটি ব্রাঞ্চের ফলাফলই String ধরনের, তাই if-else এক্সপ্রেশনের ফলাফলও
String ধরনের। এই উদাহরণে, answerString-কে if-else এক্সপ্রেশনের ফলাফল থেকে একটি প্রাথমিক
মান অ্যাসাইন করা হয়েছে। answerString-এর জন্য স্পষ্ট ধরনের ঘোষণা বাদ দিতে টাইপ ইনফারেন্স ব্যবহার করা যেতে পারে, তবে স্পষ্টতার জন্য এটি অন্তর্ভুক্ত করা প্রায়শই একটি ভাল
ধারণা।
আপনার কন্ডিশনাল স্টেটমেন্ট যত জটিল হবে, আপনি হয়ত আপনার if-else এক্সপ্রেশনকে when এক্সপ্রেশন দিয়ে পরিবর্তন করার কথা বিবেচনা করতে পারেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
val answerString = when {
count == 42 -> "I have the answer."
count > 35 -> "The answer is close."
else -> "The answer eludes me."
}
println(answerString)
when এক্সপ্রেশনের প্রতিটি শাখা একটি কন্ডিশন, একটি তীরচিহ্ন
(->) এবং একটি ফলাফল দ্বারা উপস্থাপিত হয়। তীরচিহ্নের বাঁদিকের কন্ডিশন
সঠিক হলে, ডানদিকের এক্সপ্রেশনের ফলাফল
রিটার্ন করা হয়। মনে রাখবেন, একটি ব্রাঞ্চ থেকে অন্য ব্রাঞ্চে এক্সিকিউশন ফল থ্রু হয় না।
when এক্সপ্রেশন উদাহরণের কোডটি আগের উদাহরণের কোডের
সমান কার্যকারিতা সম্পন্ন, তবে এটি আরও সহজে পড়া যায়।
Kotlin-এর কন্ডিশনাল, এর আরও শক্তিশালী ফিচারগুলির মধ্যে একটি, স্মার্ট কাস্টিং হাইলাইট করে। নাল ভ্যালুর সাথে কাজ করার জন্য সেফ-কল অপারেটর বা নট-নাল অ্যাসার্শন অপারেটর ব্যবহার করার পরিবর্তে, আপনি কন্ডিশনাল স্টেটমেন্ট ব্যবহার করে কোনও ভেরিয়েবলে নাল ভ্যালুর রেফারেন্স আছে কিনা তা চেক করতে পারেন, যেমন নিচের উদাহরণে দেখানো হয়েছে:
val languageName: String? = null
if (languageName != null) {
// No need to write languageName?.toUpperCase()
println(languageName.toUpperCase())
}
কন্ডিশনাল ব্রাঞ্চের মধ্যে, languageName-কে নন-নাল হিসেবে বিবেচনা করা হতে পারে।
Kotlin এটি বুঝতে পারে যে branch
এক্সিকিউট করার শর্ত হল languageName-এ কোনও null ভ্যালু নেই, তাই আপনাকে সেই branch-এর মধ্যে
languageName-কে nullable হিসেবে ট্রিট করতে হবে না। এই স্মার্ট কাস্টিং নাল
চেক,
টাইপ চেক,
বা এমন যেকোনও কন্ডিশনের ক্ষেত্রে কাজ করে যা
চুক্তি পূরণ করে।
অপেক্ষক
আপনি এক বা একাধিক এক্সপ্রেশনকে একটি ফাংশনে গ্রুপ করতে পারেন। প্রতিবার ফলাফল পাওয়ার জন্য একই এক্সপ্রেশনের সিরিজ পুনরাবৃত্তি করার পরিবর্তে, আপনি এক্সপ্রেশনগুলিকে একটি ফাংশনে র্যাপ করতে এবং তার পরিবর্তে সেই ফাংশনটি কল করতে পারেন।
ফাংশন ঘোষণা করতে, fun কীওয়ার্ড ব্যবহার করুন, তারপরে ফাংশনের নাম লিখুন।
এরপরে, আপনার ফাংশন কোনও ইনপুট নিলে তার ধরন নির্ধারণ করুন এবং
সেটি যে ধরনের আউটপুট রিটার্ন করে তা ঘোষণা করুন। ফাংশনের বডিতে আপনি
এক্সপ্রেশন সংজ্ঞায়িত করেন যা আপনার ফাংশন ইনভোক করা হলে কল করা হয়।
আগের উদাহরণগুলির উপর ভিত্তি করে, এখানে একটি সম্পূর্ণ Kotlin ফাংশন দেওয়া হল:
fun generateAnswerString(): String {
val answerString = if (count == 42) {
"I have the answer."
} else {
"The answer eludes me"
}
return answerString
}
উপরের উদাহরণে ফাংশনের নাম generateAnswerString। এতে
কোনও ইনপুট দিতে হয় না। এটি String ধরনের ফলাফল আউটপুট করে। ফাংশন কল করতে, এর নাম এবং তারপরে ইনভোকেশন অপারেটর (()) ব্যবহার করুন।
নিচের উদাহরণে, answerString ভেরিয়েবলটি generateAnswerString() থেকে পাওয়া ফলাফল দিয়ে
ইনিশিয়ালাইজ করা হয়েছে।
val answerString = generateAnswerString()
নিচের উদাহরণে দেখানো হয়েছে যে ফাংশন ইনপুট হিসেবে আর্গুমেন্ট নিতে পারে:
fun generateAnswerString(countThreshold: Int): String {
val answerString = if (count > countThreshold) {
"I have the answer."
} else {
"The answer eludes me."
}
return answerString
}
ফাংশন ঘোষণা করার সময়, আপনি যেকোনও সংখ্যক আর্গুমেন্ট ও সেগুলির
টাইপ নির্দিষ্ট করতে পারবেন। উপরের উদাহরণে, generateAnswerString() একটি আর্গুমেন্ট নেয় যার নাম
countThreshold এবং ধরন Int। ফাংশনের মধ্যে, আপনি এর নাম ব্যবহার করে
আর্গুমেন্ট উল্লেখ করতে পারবেন।
এই ফাংশন কল করার সময়, আপনাকে ফাংশন কলের বন্ধনীর মধ্যে একটি আর্গুমেন্ট যোগ করতে হবে:
val answerString = generateAnswerString(42)
ফাংশন ঘোষণা সরলীকরণ করা
generateAnswerString() একটি মোটামুটি সহজ ফাংশন। ফাংশনটি একটি
ভেরিয়েবল ঘোষণা করে এবং তারপরে সাথে সাথেই রিটার্ন করে। ফাংশন থেকে কোনও এক্সপ্রেশনের ফলাফল
রিটার্ন করা হলে, আপনি সরাসরি ফাংশনে থাকা if-else এক্সপ্রেশনের ফলাফল রিটার্ন করে
লোকাল ভেরিয়েবল ঘোষণা করা এড়িয়ে যেতে পারেন, যেমন
নিচের উদাহরণে দেখানো হয়েছে:
fun generateAnswerString(countThreshold: Int): String {
return if (count > countThreshold) {
"I have the answer."
} else {
"The answer eludes me."
}
}
এছাড়াও, আপনি অ্যাসাইনমেন্ট অপারেটরের মাধ্যমে রিটার্ন কীওয়ার্ড রিপ্লেস করতে পারবেন:
fun generateAnswerString(countThreshold: Int): String = if (count > countThreshold) {
"I have the answer"
} else {
"The answer eludes me"
}
অ্যানোনিমাস ফাংশন
প্রতিটি ফাংশনের নাম থাকতে হবে না। কিছু ফাংশন তাদের ইনপুট ও আউটপুট দ্বারা আরও সরাসরি শনাক্ত করা হয়। এইসব ফাংশনকে অ্যানোনিমাস ফাংশন বলা হয়। আপনি অ্যাননিমাস ফাংশনের রেফারেন্স রাখতে পারেন, এই রেফারেন্স ব্যবহার করে পরে অ্যাননিমাস ফাংশন কল করতে পারেন। এছাড়াও, আপনি অন্যান্য রেফারেন্সের ধরনের মতো আপনার অ্যাপ্লিকেশনের চারপাশে রেফারেন্স পাস করতে পারেন।
val stringLengthFunc: (String) -> Int = { input ->
input.length
}
নামযুক্ত ফাংশনের মতো, বেনামী ফাংশনেও যেকোনও সংখ্যক এক্সপ্রেশন থাকতে পারে। ফাংশনের রিটার্ন করা ভ্যালু হল চূড়ান্ত এক্সপ্রেশনের ফলাফল।
উপরের উদাহরণে, stringLengthFunc-এ একটি বেনামী
ফাংশনের রেফারেন্স আছে যা String-কে ইনপুট হিসেবে নেয় এবং ইনপুটের দৈর্ঘ্যকে
String আউটপুট হিসেবে রিটার্ন করে, যার ধরন হল Int। এই কারণে, ফাংশনের ধরনকে
(String) -> Int হিসেবে চিহ্নিত করা হয়েছে। তবে, এই কোডটি ফাংশনকে ইনভোক করে না।
ফাংশনের ফলাফল পেতে, আপনাকে অবশ্যই এটিকে কোনও
নামযুক্ত ফাংশনের মতো ইনভোক করতে হবে। String-এ কল করার সময় আপনাকে অবশ্যই stringLengthFunc দিতে হবে, যেমন
নিচের উদাহরণে দেখানো হয়েছে:
val stringLengthFunc: (String) -> Int = { input ->
input.length
}
val stringLength: Int = stringLengthFunc("Android")
উচ্চ-ক্রমের ফাংশন
কোনও ফাংশন আর্গুমেন্ট হিসেবে অন্য ফাংশন নিতে পারে। যেসব ফাংশন আর্গুমেন্ট হিসেবে অন্য ফাংশন ব্যবহার করে সেগুলিকে উচ্চ-ক্রমের ফাংশন বলা হয়। এই প্যাটার্নটি একইভাবে কম্পোনেন্টগুলির মধ্যে যোগাযোগ করার জন্য উপযোগী, যেভাবে আপনি Java-তে কলব্যাক ইন্টারফেস ব্যবহার করতে পারেন।
এখানে একটি উচ্চ-ক্রমের ফাংশনের উদাহরণ দেওয়া হল:
fun stringMapper(str: String, mapper: (String) -> Int): Int {
// Invoke function
return mapper(str)
}
stringMapper() ফাংশনটি একটি String-এর সাথে এমন একটি ফাংশন নেয় যা
আপনি এতে পাস করেন এমন একটি String থেকে Int ভ্যালু পায়।
আপনি String পাস করে stringMapper() কল করতে পারেন এবং এমন একটি ফাংশন যা
অন্য ইনপুট প্যারামিটারকে সন্তুষ্ট করে, অর্থাৎ এমন একটি ফাংশন যা ইনপুট হিসেবে String নেয় এবং Int আউটপুট দেয়, যেমনটি
নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
stringMapper("Android", { input ->
input.length
})
অনামেয় ফাংশনটি যদি কোনও ফাংশনে সংজ্ঞায়িত শেষ প্যারামিটার হয়, তাহলে আপনি ফাংশনটি ইনভোক করার জন্য ব্যবহৃত প্যারেন্থেসিসের বাইরে এটি পাস করতে পারবেন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
stringMapper("Android") { input ->
input.length
}
Kotlin স্ট্যান্ডার্ড লাইব্রেরি জুড়ে বেনামী ফাংশন দেখা যেতে পারে। আরও তথ্যের জন্য, উচ্চ-ক্রমের ফাংশন ও ল্যাম্বডা দেখুন।
ক্লাস
এতক্ষণ ধরে উল্লেখ করা সব ধরনের ডেটা Kotlin প্রোগ্রামিং
ল্যাঙ্গুয়েজে বিল্ট-ইন হিসেবে থাকে। আপনি নিজের কাস্টম ধরন যোগ করতে চাইলে, নিম্নলিখিত উদাহরণে দেখানো class কীওয়ার্ড ব্যবহার করে
একটি ক্লাস ডিফাইন করতে পারেন:
class Car
প্রপার্টি
ক্লাস, প্রপার্টি ব্যবহার করে স্টেটকে উপস্থাপন করে। একটি
প্রপার্টি হল
ক্লাস-লেভেল ভেরিয়েবল যার মধ্যে গেটার, সেটার ও ব্যাকগ্রাউন্ড ফিল্ড থাকতে পারে।
যেহেতু গাড়ি চালানোর জন্য চাকা প্রয়োজন, তাই আপনি নিম্নলিখিত উদাহরণে দেখানো Car-এর প্রপার্টি হিসেবে Wheel অবজেক্টের একটি তালিকা যোগ করতে পারেন:
class Car {
val wheels = listOf<Wheel>()
}
মনে রাখবেন, wheels হল একটি public val, অর্থাৎ wheels-কে Car ক্লাসের বাইরে থেকে অ্যাক্সেস করা যাবে এবং এটি আবার অ্যাসাইন করা যাবে না। আপনি যদি Car-এর
ইনস্ট্যান্স পেতে চান, তাহলে আপনাকে প্রথমে এর কনস্ট্রাক্টরকে কল করতে হবে। সেখান থেকে, আপনি
এর অ্যাক্সেস করা যায় এমন যেকোনও প্রপার্টি অ্যাক্সেস করতে পারবেন।
val car = Car() // construct a Car
val wheels = car.wheels // retrieve the wheels value from the Car
আপনি যদি নিজের চাকা কাস্টমাইজ করতে চান, তাহলে আপনি একটি কাস্টম কনস্ট্রাক্টরকে সংজ্ঞায়িত করতে পারেন যা আপনার ক্লাস প্রপার্টি কীভাবে ইনিশিয়ালাইজ করা হয় তা নির্দিষ্ট করে:
class Car(val wheels: List<Wheel>)
উপরের উদাহরণে, ক্লাস কনস্ট্রাক্টর List<Wheel>-কে কনস্ট্রাক্টর আর্গুমেন্ট হিসেবে নেয় এবং সেটির wheels
প্রপার্টি ইনিশিয়ালাইজ করতে সেই আর্গুমেন্ট ব্যবহার করে।
ক্লাস ফাংশন ও এনক্যাপসুলেশন
আচরণ মডেল করার জন্য ক্লাস ফাংশন ব্যবহার করে। ফাংশন স্টেট পরিবর্তন করতে পারে, এর ফলে আপনি শুধুমাত্র সেই ডেটা প্রকাশ করতে পারেন যা আপনি প্রকাশ করতে চান। এই অ্যাক্সেস কন্ট্রোল হল এনক্যাপসুলেশন নামে পরিচিত একটি বৃহত্তর অবজেক্ট-ওরিয়েন্টেড কনসেপ্টের অংশ।
নিচের উদাহরণে, Car ক্লাসের বাইরে থেকে কোনও কিছুকে doorLock প্রপার্টি
থেকে ব্যক্তিগত রাখা হয়েছে। গাড়ি আনলক করতে, আপনাকে অবশ্যই unlockDoor()
ফাংশন কল করতে হবে এবং নিম্নলিখিত উদাহরণে দেখানো বৈধ কী পাস করতে হবে:
class Car(val wheels: List<Wheel>) {
private val doorLock: DoorLock = ...
fun unlockDoor(key: Key): Boolean {
// Return true if key is valid for door lock, false otherwise
}
}
কোনও প্রপার্টি কীভাবে রেফারেন্স করা হবে তা কাস্টমাইজ করতে চাইলে, আপনি
কাস্টম গেটার ও সেটার প্রদান করতে পারেন। যেমন, আপনি যদি কোনও প্রপার্টির
গেটারকে এক্সপোজ করতে চান, কিন্তু সেটার সেটারকে অ্যাক্সেস করতে দিতে না চান, তাহলে আপনি সেই সেটারকে
private হিসেবে চিহ্নিত করতে পারেন:
class Car(val wheels: List<Wheel>) {
private val doorLock: DoorLock = ...
var gallonsOfFuelInTank: Int = 15
private set
fun unlockDoor(key: Key): Boolean {
// Return true if key is valid for door lock, false otherwise
}
}
প্রপার্টি ও ফাংশনের কম্বিনেশনের সাহায্যে, আপনি এমন ক্লাস তৈরি করতে পারবেন যা সব ধরনের অবজেক্টের মডেল তৈরি করে।
ইন্টারঅপারেবিলিটি
Kotlin-এর সবচেয়ে গুরুত্বপূর্ণ ফিচারগুলির মধ্যে একটি হল Java-র সাথে এর সাবলীল ইন্টার-অপারেবিলিটি। Kotlin কোড JVM বাইটকোডে কম্পাইল করা হয় বলে, আপনার Kotlin কোড সরাসরি Java কোডে কল করতে পারে এবং এর বিপরীতও হতে পারে। এর অর্থ হল, আপনি Kotlin থেকে সরাসরি আগে থেকে থাকা Java লাইব্রেরি ব্যবহার করতে পারবেন। এছাড়াও, বেশিরভাগ Android API Java-তে লেখা হয় এবং আপনি সেগুলি Kotlin থেকে সরাসরি কল করতে পারবেন।
পরবর্তী ধাপ
Kotlin হল একটি নমনীয়, বাস্তবসম্মত ভাষা যা ক্রমশ আরও বেশি প্ল্যাটফর্মে কাজ করে এবং এর ব্যবহার বাড়ছে। আপনি এখনও এটি ব্যবহার করে না থাকলে, আমরা আপনাকে এটি ব্যবহার করে দেখার জন্য উৎসাহ দিই। পরবর্তী ধাপের জন্য, অফিসিয়াল Kotlin ডকুমেন্টেশন দেখে নিন, এর সাথে আপনার Android অ্যাপে কীভাবে সাধারণ Kotlin প্যাটার্ন প্রয়োগ করবেন সেই সংক্রান্ত নির্দেশিকাও দেখুন।