آموزش زبان کاتلین – درس ۱۷ (کلاس و اشیاء)

نویسنده : سید ایوب کوکبی ۹ آذر ۱۳۹۷

آموزش زبان کاتلین – درس 17 (کلاس و اشیاء)

در کاتلین ، هم امکان برنامه‌نویسی فانکشنال و هم شی‌گراء وجود دارد. این زبان با ویژگی‌های خوبی نظیر توابع top-level و لامبدا انتخاب مناسبی جهت کدنویسی فانکشنال است که در درس‌های بعدی به آن خواهیم پرداخت. در این مقاله تاکید روی ویژگی‌های شی‌گرایی زبان کاتلین است.

برنامه‌نویسی شی‌گراء در کاتلین (OOP)

در پارادایم شی‌گراء می‌توانید یک مسئله‌ی بزرگ را به مجموعه‌ای از قطعات کوچکتر تحت عنوان اشیاء (Object) تقسیم کنید.

هر شی‌ء دو ویژگی دارد:

  • حالت (State)
  • رفتار (Behavior)

مثلاً لامپ یک شیء است که از سقف اتاق شما آویزان است. این لامپ دو حالت دارد: روشن یا خاموش (شایدم حالت سوخته!) و دو رفتار روشن کردن/شدن و خاموش کردن/شدن. دوچرخه نیز شی دیگری است که دارای حالت‌هایی مثل دندۀ فعلی، تعداد دنده و رفتارهایی همچون ترمز کردن، شتاب‌گرفتن، عوض کردن دنده و … باشد. برنامه‌نویسی شی‌گرا بحث گسترده‌ای است. ان‌شاءا… بعداً دربارۀ کپسوله کردن اشیاء، ارث‌بری و چند‌ریختی که ویژگی‌های اصلی این سبک برنامه‌نویسی است توضیح خواهم داد. در این مقاله فعلاً روی مفاهیم پایه تمرکز خواهیم کرد.

کلاس (Class)

قبل از ساخت اشیاء در کاتلین، ابتدا باید الگویی داشته باشید که از روی آن شیء مورد نظر را بسازید. به آن الگو کلاس گفته می‌شود. تا نقشه نباشد، خانه را نمی‌توان ساخت. در دنیای برنامه‌نویسی به کلاس اصطلاحاً Blueprint گفته می‌شود. کلاس را می‌توان یک طرح انتزاعی یا همچون نقشه‌ی یک خانه تصور کرد. این نقشه تمام جزئیات ساخت خانه از قبیل درها، پنجره‌ها، موقعیت پنجره‌ها، رنگ اتاق‌ها و … را داراست. طبق این نقشه، خانه‌ی واقعی ساخته می‌شود که ما به آن شی می‌گوییم. همانطور که از روی یک نقشه، بارها و بارها می‌توان خانه‌های جدیدی ساخت. در برنامه‌نویسی نیز از روی یک کلاس می‌توان بی‌نهایت اشیاء جدید ساخت.

بخوانید  آموزش زبان کاتلین – درس 11 (حلقۀ for)

روش تعریف کلاس در کاتلین

در کاتلین کلاس‌ها با کلیدواژۀ class ساخته می‌شوند:

class Lamp {

    // property (data member)
    private var isOn: Boolean = false

    // member function
    fun turnOn() {
        isOn = true
    }

    // member function
    fun turnOff() {
        isOn = false
    }
}

در مثال بالا، کلاسی تحت عنوان Lamp تعریف کرده‌ایم. کلاس یک پراپرتی isOn (دقیقاً مثل متغیرها تعریف شده است) دارد و دو متد ()turnOn و ()turnOff. پراپرتی‌ها یا باید مقداردهی اولیه شوند یا به صورت abstract (که بعداً توضیح می‌دهم) تعریف شوند. در این مثال، isOn با false مقداردهی شده است. کلاس‌ها، اشیاء، پراپرتی‌ها و متدها همگی می‌توانند visibility داشته باشند. مثلاً پراپرتی isOn با مودیفایر private مشخص شده است. این یعنی مقدار این پراپرتی تنها داخل همین کلاس Lamp قابل تغییر است و لاغیر.

سایر مودیفایرهای مرتبط با visibility عبارتند از:

  • private: تنها داخل کلاسی که به آن متعلق است قابل روئیت است؛
  • public: همه جا قابل روئیت است (مقدار پیش‌فرض)؛
  • protected: قابل روئیت توسط کلاس و زیرکلاس‌های آن؛
  • internal: تنها داخل ماژول فعلی قابل دسترس است.

بعداً درباره‌ی مودیفایرهای protected و internal بیشتر توضیح می‌دهم. در صورتی که هیچ مودیفایری استفاده نکنید به صورت پیش‌فرض public در نظر گرفته می‌شود. در برنامۀ بالا متدهای ()turnOn و ()turnOff عمومی یا public هستند و isOn خصوصی یا private است.

اشیاء (Objects)

بعد از تعریف کلاس، نقشۀ کار آماده ولی هنوز چیزی ساخته نشده است. در واقع هیچ حافظه یا فضای ذخیره‌سازی اشغال نشده است. برای دسترسی به اعضای داخل کلاس باید از روی آن شی‌ای ساخت. بیایید از روی کلاس Lamp دو شی بسازیم:

class Lamp {

    // property (data member)
    private var isOn: Boolean = false

    // member function
    fun turnOn() {
        isOn = true
    }

    // member function
    fun turnOff() {
        isOn = false
    }
}

fun main(args: Array<String>) {

    val l1 = Lamp() // create l1 object of Lamp class
    val l2 = Lamp() // create l2 object of Lamp class
}

اینجا دو شی l1 و l2 از کلاس Lamp ساخته شده که مقدار پراپرتی isOn در هر دوی آن‌ها false است چون هنوز به مقدار اولیۀ آن‌ها دست نزده‌ایم.

بخوانید  برنامه‌نویسی پیشرفته اندروید با زبان کاتلین - بخش اول

دسترسی به اعضای کلاس

برای دسترسی به پراپرتی‌ها و اعضای کلاس از نقطه استفاده می‌کنیم. مثلاً:

l1.turnOn()

اینجا تابع ()turnOn روی شی l1 فرخوانی کرده‌ایم.

یا مثلاً:

l2.isOn = true

اینجا سعی می‌کنیم مقدار پراپرتی isOn در شی l2 را به true تغییر دهیم. اما چون isOn به صورت private تعریف شده چنین امکانی وجود ندارد و کامپایلر خطا می‌دهد. در واقع فقط داخل خودِ کلاس Lamp می‌توان این پراپرتی را تغییر داد که این کار از عهدۀ متدهای آن کلاس برمی‌آید.

مثال کاملی از کلاس و اشیاء در کاتلین

class Lamp {

    // property (data member)
    private var isOn: Boolean = false

    // member function
    fun turnOn() {
        isOn = true
    }

    // member function
    fun turnOff() {
        isOn = false
    }

    fun displayLightStatus(lamp: String) {
        if (isOn == true)
            println("$lamp lamp is on.")
        else
            println("$lamp lamp is off.")
    }
}

fun main(args: Array<String>) {

    val l1 = Lamp() // create l1 object of Lamp class
    val l2 = Lamp() // create l2 object of Lamp class

    l1.turnOn()
    l2.turnOff()

    l1.displayLightStatus("l1")
    l2.displayLightStatus("l2")
}

خروجی:

l1 Lamp is on.
l2 Lamp is off.

در برنامۀ بالا:

  • کلاس Lamp ایجاد شده است؛
  • این کلاس یک پراپرتی isOn و سه متد ()turnOn(), turnOff و ()displayLightStatus دارد؛
  • دو شی l1 و l2 از کلاس Lamp در داخل متد ()main ساخته شده‌اند؛
  • در اینجا تابع ()turnOn توسط شی l1 فرخوانی می‌شود: ()l1.turnOn. این متد کارش تغییر مقدار پراپرتی isOn به true است؛
  • و تابع ()turnOff روی شی l2 فرخوانی شده است: ()l2.turnOff. این متد نیز مقدار متغیر l2 را به false تغییر می‌دهد؛
  • سپس تابع ()displayLightStatus روی دو شی l1 و l2 فرخوانی شده است. این متد نیز بر حسب مقدار isOn پیغام مناسبی را در خروجی چاپ می‌کند.
بخوانید  آموزش زبان کاتلین - درس 1 (ساخت اولین برنامه)

توجه کنید که پراپرتی isOn داخل کلاس، مقدار پیش‌فرض false دارد بنابراین وقتی شی یا آبجکتی از کلاس می‌سازیم مقدار این متغیر به صورت خودکار false تعیین می‌شود. به همین خاطر نیازی نیست که با فرخوانی تابع ()turnOff روی شی l2 مقدار isOn را false کنیم.

class Lamp {

    // property (data member)
    private var isOn: Boolean = false

    // member function
    fun turnOn() {
        isOn = true
    }

    // member function
    fun turnOff() {
        isOn = false
    }

    fun displayLightStatus() {
        if (isOn == true)
            println("lamp is on.")
        else
            println("lamp is off.")
    }
}

fun main(args: Array<String>) {

    val lamp = Lamp()
    lamp.displayLightStatus()
}

خروجی:

lamp is off.

خب، برای شروع، همین مقدار کافی است. در درس‌های بعدی جزئیات بیشتری از برنامه‌نویسی شی‌گرا و قابلیت‌های زبان کاتلین در این رابطه ارائه خواهم داد.

سید ایوب کوکبی

نویسنده و مترجم...

0 دیدگاه

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *