Sealed Class — τι είναι, αρχή λειτουργίας και εφαρμογή

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-05-26 Χρόνος ανάγνωσης: 8 λεπ

Sealed Class — ένας ειδικός τύπος κλάσης στην Kotlin που περιορίζει την ιεραρχία κληρονομικότητας σε ένα σταθερό σύνολο υποτύπων. Όλοι οι κληρονόμοι δηλώνονται στο ίδιο αρχείο και είναι γνωστοί στον μεταγλωττιστή, επιτρέποντας τη χρήση ενός εξαντλητικού μπλοκ when χωρίς υποχρεωτικό else κλάδο. Σύμφωνα με το Kotlin Docs, 2026, οι σφραγισμένες κλάσεις αποτελούν βασικό μηχανισμό για την αναπαράσταση περιορισμένων ιεραρχιών, όπως καταστάσεις, τύποι σφαλμάτων και συμβάντα UI.

Κύρια σημεία

  • Sealed Class — κλάση με σταθερό σύνολο κληρονόμων που δηλώνονται στο ίδιο αρχείο.
  • Exhaustive when — ο μεταγλωττιστής ελέγχει ότι όλοι οι υποτύποι έχουν υποστεί επεξεργασία, εξαλείφοντας ξεχασμένους else κλάδους.
  • Sealed interface — Kotlin 1.5+ υποστηρίζει σφραγισμένες διεπαφές για πολλαπλή κληρονομικότητα.
  • Ιεραρχία σφαλμάτων — το sealed class είναι ο τυπικός τρόπος ασφαλούς τύπου διαχείρισης σφαλμάτων στην Kotlin.
  • Διαφορά από το enum — κάθε κληρονόμος του sealed class μπορεί να περιέχει μοναδική κατάσταση και διαφορετικό αριθμό πεδίων.

Τι είναι το Sealed Class;

Sealed Class (σφραγισμένη κλάση) — είναι μια κλάση στην Kotlin σημαδεμένη με τον τροποποιητή sealed. Ορίζει μια περιορισμένη ιεραρχία τύπων: όλοι οι πιθανοί κληρονόμοι απαριθμούνται στο ίδιο αρχείο και ο μεταγλωττιστής γνωρίζει για τον καθένα. Αυτό διακρίνει το sealed class από μια συνηθισμένη ανοικτή κλάση, της οποίας οι κληρονόμοι μπορούν να δηλωθούν οπουδήποτε.

Ο κύριος σκοπός του sealed class είναι η ασφαλής τύπου αναπαράσταση ενός πεπερασμένου συνόλου παραλλαγών. Κάθε κληρονόμος μπορεί να έχει τη δική του δομή δεδομένων, καθιστώντας το sealed class πιο ευέλικτο από το enum. Κατά τον χρόνο εκτέλεσης, το sealed class είναι μια συνηθισμένη αφηρημένη κλάση, ο μεταγλωττιστής επιβάλλει περιορισμούς μόνο στο στάδιο μεταγλώττισης.

Το Sealed class είναι ιδιαίτερα χρήσιμο στην αρχιτεκτονική Android εφαρμογών: καταστάσεις UI, αποτελέσματα αιτημάτων δικτύου, συμβάντα πλοήγησης τύπου Intent και φυσικά ιεραρχίες σφαλμάτων — τυπικά σενάρια εφαρμογής.

Κατά τη μεταγλώττιση, το sealed class βελτιστοποιείται σε πίνακα μεταβάσεων για εκφράσεις when, καθιστώντας το πιο αποδοτικό από τις αλυσίδες if-else. Σε συνδυασμό με το data class, κάθε κληρονόμος μπορεί να περιέχει όχι μόνο κατάσταση, αλλά και μεθόδους, επιτρέποντας τη δημιουργία αυτοτεκμηριούμενων μοντέλων τομέα χωρίς boilerplate κώδικα.

Το Sealed class είναι επίσης αποτελεσματικό για την αναπαράσταση πεπερασμένων αυτομάτων (state machine) σε εφαρμογές για κινητά. Κάθε κατάσταση — ξεχωριστός κληρονόμος με μοναδικές παραμέτρους, και οι μεταβάσεις μεταξύ καταστάσεων ελέγχονται μέσω της έκφρασης when. Ο μεταγλωττιστής εγγυάται ότι όλες οι πιθανές καταστάσεις έχουν υποστεί επεξεργασία, εξαλείφοντας σφάλματα χρόνου εκτέλεσης κατά την αλλαγή κατάστασης UI ή επιχειρηματικής λογικής.

Sealed Class και Enum: βασικές διαφορές

Οι αρχάριοι προγραμματιστές Kotlin συχνά μπερδεύουν το sealed class με το enum, καθώς και τα δύο περιορίζουν το σύνολο τιμών. Ωστόσο, υπάρχει θεμελιώδης διαφορά μεταξύ τους: το enum — είναι ένα σύνολο σταθερών του ίδιου τύπου, το sealed class — μια ιεραρχία διαφορετικών τύπων.

Πότε να επιλέξετε enum

Enum είναι βέλτιστο όταν όλες οι παραλλαγές είναι σταθερές χωρίς πρόσθετη δομή. Για παράδειγμα, ημέρες της εβδομάδας, καταστάσεις παραγγελίας ή τύποι ενεργειών χωρίς παραμέτρους. Κάθε τιμή enum είναι ένα singleton με σταθερό όνομα.

Πότε να επιλέξετε sealed class

Sealed class απαιτείται όταν κάθε παραλλαγή έχει τα δικά της δεδομένα. Για παράδειγμα, ένα σφάλμα δικτύου περιέχει κωδικό απόκρισης, ένα σφάλμα ανάλυσης — λεπτομέρειες, και ένα σφάλμα εξουσιοδότησης — μήνυμα. Κάθε κληρονόμος του sealed class είναι ένας ξεχωριστός τύπος με μοναδικά πεδία.

kotlin
// Enum — όλες οι παραλλαγές ενός τύπου
enum class Status { LOADING, SUCCESS, ERROR }

// Sealed class — κάθε παραλλαγή με δικά της δεδομένα
sealed class UiState<out T> {
    object Loading : UiState<Nothing>()
    data class Success<T>(val data: T) : UiState<T>()
    data class Error(val message: String) : UiState<Nothing>()
}

Sealed Interface εναντίον Sealed Class

Από την Kotlin 1.5, υπάρχει η δυνατότητα δήλωσης sealed interface. Αυτό επεκτείνει την έννοια sealed στις διεπαφές: το sealed interface έχει επίσης σταθερό σύνολο υλοποιήσεων, αλλά υποστηρίζει πολλαπλή κληρονομικότητα.

Πότε να χρησιμοποιήσετε sealed interface

Sealed interface είναι βολικό όταν οι κληρονόμοι πρέπει να υλοποιούν πολλαπλές συμβάσεις ταυτόχρονα. Για παράδειγμα, ένα συμβάν UI μπορεί να είναι ταυτόχρονα κλικάσιμο και ιχνηλάσιμο. Με sealed class θα έπρεπε να επιλέξετε μία βασική κλάση, με sealed interface ο κληρονόμος υλοποιεί και τα δύο.

Περιορισμοί του sealed class

Sealed class είναι μια κλάση, επομένως κάθε κληρονόμος μπορεί να έχει μόνο έναν γονέα. Το Sealed interface λύνει αυτό το πρόβλημα, αλλά δεν μπορεί να περιέχει κατάσταση. Η επιλογή μεταξύ τους εξαρτάται από την εργασία: χρειάζεται κοινή λογική με πεδία — sealed class, χρειάζεται ευελιξία συμβάσεων — sealed interface.

kotlin
sealed interface ScreenEvent {
    data class Refresh(val force: Boolean) : ScreenEvent
    data class Navigate(val route: String) : ScreenEvent
    data class ShowError(val toast: String) : ScreenEvent
}

sealed interface AnalyticsEvent {
    val name: String
    val params: Map<String, Any>
}

// Ο κληρονόμος υλοποιεί και τις δύο διεπαφές
data class LoginClicked(
    override val name: String = "login_click",
    override val params: Map<String, Any> = emptyMap()
) : ScreenEvent, AnalyticsEvent

Sealed Class για ιεραρχία σφαλμάτων στην ανάπτυξη εφαρμογών για κινητά

Μία από τις κύριες εφαρμογές του sealed class στην ανάπτυξη εφαρμογών για κινητά — ασφαλής τύπου ιεραρχία σφαλμάτων. Αντί να ρίχνετε εξαιρέσεις διαφορετικών τύπων ή να χρησιμοποιείτε γενικό Exception, το sealed class συλλέγει όλα τα πιθανά σφάλματα τομέα σε έναν τύπο.

Πώς να δημιουργήσετε ιεραρχία σφαλμάτων

Δημιουργήστε ένα sealed class DomainError και απαριθμήστε όλους τους τύπους αποτυχίας ως κληρονόμους. Κάθε κληρονόμος περιέχει μόνο τα δεδομένα που έχουν νόημα για αυτόν τον τύπο σφάλματος. Ο μεταγλωττιστής εγγυάται ότι κατά την επεξεργασία του σφάλματος δεν θα ξεχάσετε καμία παραλλαγή.

Παράδειγμα: διαχείριση σφαλμάτων αυθεντικοποίησης

Ας εξετάσουμε μια εφαρμογή με εξουσιοδότηση, όπου είναι δυνατά διαφορετικά σενάρια αποτυχίας: λάθος κωδικός, αποκλεισμός λογαριασμού, πρόβλημα διακομιστή. Το Sealed class τα ενώνει σε έναν ενιαίο τύπο με εξαντλητική διαχείριση.

kotlin
sealed class AuthError {
    data class InvalidCredentials(
        val attempts: Int
    ) : AuthError()

    data class AccountBlocked(
        val until: Long
    ) : AuthError()

    data class NetworkFailure(
        val cause: Throwable
    ) : AuthError()

    object ServerError : AuthError()
}

fun handleError(error: AuthError): String = when (error) {
    is AuthError.InvalidCredentials ->
        "Απομένουν προσπάθειες: ${3 - error.attempts}"
    is AuthError.AccountBlocked ->
        "Η πρόσβαση αποκλείστηκε έως ${Date(error.until)}"
    is AuthError.NetworkFailure ->
        "Ελέγξτε τη σύνδεση: ${error.cause.localizedMessage}"
    AuthError.ServerError ->
        "Ο διακομιστής είναι προσωρινά μη διαθέσιμος"
}

Μοτίβα χρήσης Sealed Class στο Android

Sealed class έχει γίνει standard εργαλείο στην αρχιτεκτονική εφαρμογών Android. Ας εξετάσουμε τρία βασικά μοτίβα όπου το sealed class είναι απαραίτητο στην ανάπτυξη εφαρμογών για κινητά.

  • UI State — αναπαράσταση οθόνης ως πεπερασμένου αυτόματου: Loading, Content, Error. Κάθε κατάσταση περιέχει τα δικά της δεδομένα, και το sealed class εγγυάται ότι όλες οι μεταβάσεις έχουν υποστεί επεξεργασία.
  • Navigation Event — sealed class αντί για σταθερές πλοήγησης: κάθε οθόνη είναι ξεχωριστός κληρονόμος με παραμέτρους διαδρομής. Ο μεταγλωττιστής ελέγχει τους τύπους ορισμάτων.
  • Action/Intent — το μοτίβο Unidirectional Data Flow χρησιμοποιεί sealed class για την αναπαράσταση όλων των ενεργειών που μπορεί να εκτελέσει ο χρήστης στην οθόνη.

Ξεχωριστά, αξίζει να αναφερθεί η εφαρμογή του sealed class στην Clean Architecture. Κάθε επίπεδο (data, domain, presentation) χρησιμοποιεί sealed class για τους δικούς του τύπους σφαλμάτων, και οι mapper μετατρέπουν ένα sealed class σε άλλο. Για παράδειγμα, το DataError από το επίπεδο δεδομένων αντιστοιχίζεται σε DomainError για την επιχειρηματική λογική και στη συνέχεια σε UiState για το επίπεδο παρουσίασης. Αυτό διατηρεί την ασφάλεια τύπου σε όλα τα επίπεδα της εφαρμογής και εγγυάται ότι κανένα σφάλμα δεν θα παραμείνει ανεπεξέργαστο.

Δοκιμή ιεραρχιών sealed class

Δοκιμή του sealed class απαιτεί ειδική προσέγγιση, καθώς κάθε κληρονόμος είναι ξεχωριστός τύπος με δική του κατάσταση. Συνιστάται η σύνταξη παραμετροποιημένων δοκιμών που διέρχονται από όλους τους κληρονόμους του sealed class. Αυτό εγγυάται ότι οι εκφράσεις when καλύπτουν όλες τις παραλλαγές, συμπεριλαμβανομένων των νέων που προστίθενται κατά την επέκταση της ιεραρχίας.

Για δοκιμές UI, το sealed class ως UiState επιτρέπει τον έλεγχο εμφάνισης κάθε κατάστασης: Loading δείχνει spinner, Content — δεδομένα, Error — μήνυμα σφάλματος. Δεδομένου ότι το sealed class είναι πεπερασμένο, η κάλυψη δοκιμών όλων των καταστάσεων παρέχει πλήρη βεβαιότητα για την ορθότητα της λογικής UI.

Συνήθη λάθη κατά την εργασία με Sealed Class

Παρά την απλότητα της έννοιας, οι προγραμματιστές κάνουν τακτικά λάθη κατά τον σχεδιασμό ιεραρχιών sealed class. Ας εξετάσουμε τα κύρια προβλήματα και τρόπους αποφυγής τους.

  • Κληρονόμοι σε διαφορετικά αρχεία — ο μεταγλωττιστής δεν θα επιτρέψει τη δήλωση sealed class εάν οι κληρονόμοι βρίσκονται εκτός αρχείου. Αυτός ο περιορισμός εγγυάται εξαντλητικό when.
  • Ανάμειξη sealed και open — το sealed class δεν μπορεί να είναι ταυτόχρονα open. Εάν χρειάζεται επεκτάσιμη ιεραρχία, χρησιμοποιήστε συνηθισμένο abstract class, αλλά θα θυσιάσετε την εξαντλητικότητα.
  • Υπερβολική ένθεση — sealed class μέσα σε sealed class δημιουργεί βαθιά ιεραρχία που είναι δύσκολο να συντηρηθεί. Για απλά σενάρια, δύο επίπεδα είναι αρκετά.
  • Ξεχασμένο else στο when — εάν το sealed class από βιβλιοθήκη δεν έχει εξαντλητικότητα, ο μεταγλωττιστής δεν θα προειδοποιήσει για τον κλάδο που παραλείφθηκε. Προσθέστε το else μόνο συνειδητά.

Συχνές Ερωτήσεις

Μπορεί το sealed class να έχει αφηρημένες μεθόδους;

Ναι, το sealed class μπορεί να περιέχει αφηρημένες μεθόδους, και κάθε κληρονόμος υποχρεούται να τις υλοποιήσει. Είναι βολικό όταν όλες οι παραλλαγές πρέπει να παρέχουν μια κοινή διεπαφή, αλλά με διαφορετική λογική εκτέλεσης.

Είναι διαθέσιμο το sealed class στην Java;

Στην Java 17+ εμφανίστηκαν σφραγισμένες κλάσεις και διεπαφές με τον τροποποιητή sealed. Το Android υποστηρίζει προς το παρόν μερικώς την Java 17, αλλά σε έργα Kotlin, το sealed class είναι διαθέσιμο από την Kotlin 1.0 χωρίς περιορισμούς.

Μπορεί το sealed class να κληρονομήσει από άλλο sealed class;

Ναι, ένα sealed class μπορεί να είναι κληρονόμος άλλου. Η ιεραρχία sealed class παραμένει πεπερασμένη: ο μεταγλωττιστής γνωρίζει όλους τους κληρονόμους σε κάθε επίπεδο. Αυτό επιτρέπει τη δημιουργία λεπτομερών ταξινομήσεων σφαλμάτων.

Επηρεάζει το sealed class την απόδοση;

Το Sealed class δεν δημιουργεί πρόσθετο κόστος κατά τον χρόνο εκτέλεσης. Ο μεταγλωττιστής βελτιστοποιεί τις εκφράσεις when με sealed class σε πίνακες μεταβάσεων (tableswitch), που είναι ταχύτεροι από αλυσίδες if-else. Η απόδοση είναι ταυτόσημη με το enum.

Πώς να δοκιμάζουμε ιεραρχίες sealed class;

Κάθε κληρονόμος του sealed class δοκιμάζεται ξεχωριστά. Δεδομένου ότι το sealed class είναι πεπερασμένο, μπορεί να γραφτεί μια παραμετροποιημένη δοκιμή που διέρχεται από όλες τις παραλλαγές. Αυτό παρέχει πλήρη κάλυψη των κλάδων των μπλοκ when.

Σύνοψη

  • Sealed class — κλάση με σταθερό σύνολο κληρονόμων, δηλωμένων σε ένα αρχείο, παρέχοντας εξαντλητική ανάλυση when κατά τη μεταγλώττιση.
  • Κάθε κληρονόμος του sealed class μπορεί να έχει δική του δομή δεδομένων — η κύρια διαφορά από το enum, όπου όλες οι παραλλαγές είναι σταθερές του ίδιου τύπου.
  • Sealed interface (Kotlin 1.5+) υποστηρίζει πολλαπλή κληρονομικότητα, sealed class — μόνο απλή κληρονομικότητα. Η επιλογή εξαρτάται από την ανάγκη για κοινή κατάσταση.
  • Sealed class — standard μηχανισμός για ασφαλή τύπου ιεραρχία σφαλμάτων στην Kotlin: κάθε τύπος αποτυχίας είναι ξεχωριστός κληρονόμος με σχετικά πεδία.
  • Κύρια μοτίβα στο Android: UI State, Navigation Event και Action/Intent — βασίζονται στο sealed class για εγγύηση πληρότητας επεξεργασίας.
  • Αποφύγετε κληρονόμους σε διαφορετικά αρχεία, υπερβολική ένθεση και ανάμειξη sealed με open — αυτό παραβιάζει τη σύμβαση της πεπερασμένης ιεραρχίας.

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης