آموزش زبان کاتلین – درس ۲۶ (Sealed Class)

نویسنده : سید ایوب کوکبی ۲۱ دی ۱۳۹۷

از کلاس‌های Sealed زمانی استفاده می‌شود که هنگام ساخت زیرکلاس تنها محدود به موارد مشخصی باشیم. قبل از بررسی بیشتر کلاس‌های Sealed ببینیم مشکل چیست و این کلاس چه کمکی برای حل این مشکل می‌کند. به کد پایین – برگرفته از سایت رسمی کاتلین – نگاه کنید:

class Expr
class Const(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr

fun eval(e: Expr): Int =
        when (e) {
            is Const -> e.value
            is Sum -> eval(e.right) + eval(e.left)
            else ->
                throw IllegalArgumentException("Unknown expression")
        }

کلاس پایه Expr حاوی دو کلاس مشتق Const (نشانگر اعداد) و Sum (نشانگر مجموع دو عبارت) است. اینجا ناچاریم برای شرایط پیش‌فرضِ else در عبارت when از else استفاده کنیم. حالا اگر کلاس جدیدی از کلاس Expr مشتق کنیم، کامپایلر بخش else را تشخیص نداده و باگ بالقوه‌ای داخل کد باقی می‌ماند. بهتر بود کامپایلر در چنین شرایطی یعنی وقتی کلاس مشتق می‌کنیم خطای مناسبی صادر کند. برای حل این مشکل می‌توانیم از کلاس‌های Sealed استفاده کنیم. همانطور که در ابتدا گفتم، کلاس‌های Sealed ساخت subclassها را با محدودیت‌هایی اجباری همراه می‌کنند. بنابراین هنگامی که تمام زیرکلاس‌ها یک کلاس Sealed را داخل عبارت when هندل شود، دیگر نیازی به قسمت else نیست.

برای ساخت یک کلاس Sealed از مودیفایر Sealed استفاده می‌کنیم:

sealed class Expr

مثالی از کلاس‌های Sealed در کاتلین

کد بالا، بدون مشکلات قبلی:

sealed class Expr
class Const(val value: Int) : Expr()
class Sum(val left: Expr, val right: Expr) : Expr()
object NotANumber : Expr()


fun eval(e: Expr): Int =
        when (e) {
            is Const -> e.value
            is Sum -> eval(e.right) + eval(e.left)
            NotANumber -> java.lang.Double.NaN
        }

همانطور که می‌بینید خبری از else نیست. اگر کلاس جدیدی از Expr مشتق کنید، کامپایلر خطا می‌دهد مگر در when هندلش کرده باشید.

بخوانید  همه چیز درباره context در اندروید

چند نکته مهم:

  • تمام زیرکلاس‌های یک کلاس Sealed بایستی در یک فایل یکسان – یعنی همانجایی که کلاس Sealed تعریف شده – تعریف شوند؛
  • کلاس‌های Sealed به صورت پیش‌فرض abstract هستند، بنابراین نمی‌توانید از رویشان نمونه‌سازی کنید؛
  • شما نمی‌توانید سازنده غیر خصوصی برای کلاس‌های Sealed ایجاد نمایید؛ سازنده‌ها به صورت پیش‌فرض private یا خصوصی هستند.

فرق بین Enum و کلاس‌های Sealed

کلاس Enum و Sealed بسیار مشابه هم هستند. مقادیر نوع Enum نیز همانند کلاس Sealed محدود به موارد تعیین شده است. تنها فرقشان این است که Enum فقط می‌تواند یک نمونه داشته باشد در حالی که زیرکلاس‌های یک کلاس Sealed می‌توانند چندین نمونه داشته باشند.

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

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

0 دیدگاه

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