মনে করুন, একটি কাজ করতে গিয়ে কয়েকটি ক্লাস প্রয়োজন, এই ক্লাসগুলিকে আমরা একটি সেট বা গ্রুপ বলতে পারি। যেমন: একটি ফাইল ডাউনলোডে প্রয়োজন, সেক্ষেত্রে ডাউনলোডের অবস্থা (State) থাকতে পারে এরকম: ডাউনলোডিং, পজ, রিজিওম, সাকসেস, ইরর।
এখন এই ৫ রকমের কাজের ক্ষেত্রে ৫ টি ক্লাস ও আলাদা একটি সীলড ক্লাস তৈরি করা যেতে পারে। ৫ টি ক্লাসে সীলড ক্লাসকে এক্সটেন্ড করে নেয়া যায় যাতে ক্লাসগুলো একটা গ্রুপের অধীনে থাকে ও when (switch/case) ব্যবহার করা যায়।
সীলড ক্লাস/ইন্টারফেসকে এক্সটেন্ড/ইমপ্লিমেন্ট করা হয় অন্য ক্লাসে। সীলড ইন্টারফেস অন্য সাধারন ইন্টারফেসের মতই মাল্টিপল ইনহেরিটেন্স করার জন্য দরকার। সীলড ক্লাস/ইন্টারফেস তৈরির জন্য sealed কী-ওয়ার্ড ব্যবহার করতে হয়।
সীলড ক্লাসের ইনস্টেন্স/অবজেক্ট তৈরি করা যায় না।
উদাহরনের মাধ্যমে দেখি:
আমরা সীলড ইন্টারফেস ও সীলড ক্লাস একসাথে দেখবো।
প্রথমে সীলড ইন্টারফেস তৈরি করি:
sealed interface DownloadFinishStatus {
class Success(var metaData: String) : DownloadFinishStatus
class MyError(var error: String) : DownloadFinishStatus
}
যখন ডাউনলোড শেষ হবে তখন দুই রকম ভাবে শেষ হতে পারে। হয় সফলভাবে শেষ হবে (Success ক্লাস) অথবা ডাউনলোড ইরর(MyError ক্লাস) হবে। এজন্য এই ডাউনলোড শেষ হবার স্ট্যাটাস দুটিকে একটি ইন্টারফেসের (DownloadFinishStatus) ভিতরে রাখা হলো।
এখানে sealed কী-ওয়ার্ড ব্যবহার করে সীলড ইন্টারফেস তৈরি করা হয়েছে। ইন্টারফেসের ভিতরে ২টি ক্লাস নেয়া হয়েছে যাদের কনস্ট্রাক্টরে একটি করে প্যারামিটার দেয়া হয়েছে তারপর কোলন চিহ্ন দিয়ে ইমপ্লিমেন্ট করা হয়েছে ইন্টারফেসকে। এখানে যে ইন্টারফেসের ভিতরে ক্লাসগুলো নেয়া হয়েছে সেই ইন্টারফেসকেই ক্লাসগুলোতে ইমপ্লিমেন্ট করা হয়েছে।
এখন সীলড ক্লাস তৈরি করি:
ডাউনলোডের জন্য প্রয়োজন হতে পারে ডাউনলোড পজ করা আবার রিজিউম করা এবং যখন ডাউনলোড হবে প্রগ্রেস ভ্যালু সহ ডাউনলোডিং স্ট্যাটাস।
sealed class DownloadStatus : DownloadFinishStatus {
// ক্লাস, ডাটা ক্লাস, অবজেক্ট কে এক্সটেন্ড করা যাবে
data class Downloading(val progress: Int) : DownloadStatus()
object Pause : DownloadStatus()
object Resume : DownloadStatus()
}
সীলড কী-ওয়ার্ড ব্যবহার করে সীলড ক্লাস তৈরি করা হয়েছে। সীলড ক্লাসে আগের তৈরি করা ইন্টারফেসটি ইমপ্লিমেন্ট করা হয়েছে। ভিতরে ডাউনলোডিং ডাটা ক্লাসের প্রাইমারি কনস্ট্রাক্টরে প্রগ্রেস ভ্যালু দেয়ার জন্য একটি প্যারামিটার দেয়া হয়েছে যা কত শতাংশ (%) ডাউনলোড হয়েছে তা বুঝায়। ৩ টি স্ট্যাটাসের প্রথমটি ডেটা ক্লাস পরের ২টি অবজেক্ট নেয়া হয়েছে ও সবগুলোতে সীলড ক্লাসটি(DownloadStatus) এক্সটেন্ড করা হয়েছে।
সীলড ক্লাসে সীলড ইন্টারফেস ইমপ্লিমেন্ট কিংবা অন্য একটি সীলড ক্লাস এক্সটেন্ড করা যাবে প্রয়োজন অনুসারে, প্রয়োজন না হলে এক্সটেন্ড/ইমপ্লিমেন্ট করার প্রয়োজন নেই। ইন্টারফেস প্রয়োজন হবে মাল্টিপল ইনহেরিটেন্স করার জন্য। যদি একটি ক্লাস অন্য ক্লাসকে এক্সটেন্ড করে কাজ করা যায় তবে ইন্টারফেসের প্রয়োজন নেই যদি একাধিক ক্লাসকে এক্সটেন্ড করার প্রয়োজন হয় তখন ক্লাস তৈরি না করে ইন্টারফেস তৈরি করে ইচ্ছামতো ইমপ্লিমেন্ট করা যাবে।
এখন একটি ফাংশন তৈরি করি যাতে ডাউনলোডের স্ট্যাটাস পরিবর্তন হলে সেটা ধরতে পারি ও প্রয়োজনমতো কোড এক্সিকিউট করাতে পারি।
fun setDownloadStatus(downloadFinishStatus: DownloadFinishStatus) {
when(downloadFinishStatus) {
is DownloadFinishStatus.Success -> {
println("Downloaded File MetaData: ${downloadFinishStatus.metaData}")
}
is DownloadFinishStatus.MyError -> {
println("Error Message: ${downloadFinishStatus.error}")
}
is DownloadStatus.Pause -> {
println("Download Paused")
}
is DownloadStatus.Resume -> {
println("Download Resumed")
}
is DownloadStatus.Downloading -> {
println("Download Progress: ${downloadFinishStatus.progress}")
}
else -> { // উপরের সবগুলো টাইপ সেট না করলে ইলস লাগবে
println("Something Wrong")
}
}
}
এই ফাংশনের মাধ্যমে ডাউনলোডের স্ট্যাটাস প্যারামিটারে দিলে সেটা অনুসারে when স্টেটমেন্ট এক্সিকিউট হবে। when এ ইন্টারফেস ও ক্লাসের সকল ধরণের স্ট্যাটাস চেক করা হয়েছে।
এখন মেইন ফাংশন থেকে এই ফাংশনটি কল করে দেখি:
fun main() {
// val ds: DownloadStatus = DownloadStatus() // ইনস্টেন্স তৈরি করা যায় না
setDownloadStatus(DownloadStatus.Downloading(2))
setDownloadStatus(DownloadStatus.Pause)
setDownloadStatus(DownloadStatus.Resume)
setDownloadStatus(DownloadFinishStatus.MyError("Network Failure"))
setDownloadStatus(DownloadFinishStatus.Success("mp4 File Downloaded"))
}
মেইন ফাংশন থেকে বিভিন্ন স্ট্যাটাস দিয়ে ফাংশনটি কল করা হলো। আসলে যদি বাস্তবে কল করা হতো তবে এগুলো অনেকগুলো কোডের বিভিন্ন যায়গা থেকে কল করা হতো যেমন পজ বাটন ক্লিক করলে পজ স্ট্যাটাস, ইরর হলে ইরর স্ট্যাটাস এরকম।
আউটপুট এমন হবে:
Download Progress: 2
Download Paused
Download Resumed
Error Message: Network Failure
Downloaded File MetaData: mp4 File Downloaded
আউটপুট দেখে বুঝা যাচ্ছে যে যেগুলোর প্যারামিটার ছিলো সেগুলোর প্যারামিটারের ভ্যালুগুলো সহ প্রিন্ট হয়েছে যেগুলোর প্যারামিটার ছিলো না সেগুলোর ক্ষেত্রে যা লিখে দেয়া হয়েছে শুধু সেটাই প্রিন্ট হয়েছে।
