Ιδιαιτερότητες Kotlin στην ανάπτυξη κινητών: τι είναι, ποιες κατασκευές και πώς λειτουργεί

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

Η Kotlin είναι η κύρια γλώσσα για ανάπτυξη Android. Σύμφωνα με το Google Android Docs (2025), πάνω από 95% των νέων έργων Android χρησιμοποιούν Kotlin. Η κατανόηση των ιδιαιτεροτήτων της Kotlin — data class, sealed class, coroutines και scope functions — είναι υποχρεωτική απαίτηση για έναν προγραμματιστή Android.

Βασικά Σημεία

  • data class — αυτόματη δημιουργία equals/hashCode/toString/copy/componentN. Για μοντέλα δεδομένων. sealed class — περιορισμένη ιεραρχία τύπων με έλεγχο when.
  • Scope functions: let, run, with, apply, also. Διαφέρουν ανάλογα με το πλαίσιο (it vs this) και την τιμή επιστροφής.
  • Coroutines: launch (fire-and-forget), async (με αποτέλεσμα), runBlocking (γέφυρα), withContext (αλλαγή Dispatcher).
  • lifecycleScope και viewModelScope — coroutines με επίγνωση κύκλου ζωής χωρίς χειροκίνητη ακύρωση.
  • reified — διατήρηση τύπου σε inline συναρτήσεις. lateinit/lazy — καθυστερημένη αρχικοποίηση.

Κλάσεις (data class, sealed class, object, companion object)

Η Kotlin επεκτείνει τις έννοιες κλάσεων από τη Java. data class, sealed class, object και companion object — κατασκευές που δεν υπάρχουν στη Java ή υλοποιούνται διαφορετικά.

data class vs sealed class

data class — μια κλάση που δημιουργεί αυτόματα equals(), hashCode(), toString(), copy() και componentN(). Ιδανική για μοντέλα δεδομένων (DTO, Entity). Απαιτήσεις: τουλάχιστον μία παράμετρος στον κύριο κατασκευαστή, val/var, δεν μπορεί να είναι open/sealed/inner. sealed class — μια κλάση με περιορισμένη ιεραρχία υποκλάσεων. Όλες οι υποκλάσεις είναι γνωστές κατά τη μεταγλώττιση και δηλώνονται στο ίδιο αρχείο. Η έκφραση when με sealed class δεν απαιτεί κλάδο else. sealed interface (Kotlin 1.9+) — ίδιο με sealed class αλλά επιτρέπει πολλαπλή κληρονομικότητα. object — singleton, δηλώνεται με τη λέξη-κλειδί object (όχι class). Ασφαλής νήματος τεμπέλικη αρχικοποίηση. companion object — στατικά μέλη μιας κλάσης. Έχει όνομα (προεπιλογή Companion). Μπορεί να υλοποιεί διεπαφές και να έχει extension functions.

Τύπος Περιγραφή Χρήση
data classΑυτόματη δημιουργία equals, hashCode, toString, copyΜοντέλα δεδομένων, DTO, Entity
sealed classΠεριορισμένη ιεραρχία, έλεγχος whenΚαταστάσεις, Αποτέλεσμα, UI State
sealed interfacesealed class + πολλαπλή κληρονομικότηταΣυμβάντα, Ενέργειες (Kotlin 1.9+)
objectSingleton (δηλωτικό)Factory, Utility, Σταθερές
companion objectΣτατικά μέλη κλάσηςFactory Method, στατικές σταθερές
enum classΑπαρίθμηση με σταθερέςΚαταστάσεις με σταθερό σύνολο

data class — για το 90% των μοντέλων. sealed class — για UI State και Αποτέλεσμα. object — για singleton. Η IT Sectr συνιστά sealed class για όλες τις καταστάσεις οθόνης (Loading, Success, Error).

Sealed class στην πράξη

Sealed class — ένα ισχυρό εργαλείο για τη μοντελοποίηση καταστάσεων. Παράδειγμα: UiState<T> με υποκλάσεις Loading, Success(data: T), Error(message: String). Η έκφραση when εγγυάται τον χειρισμό όλων των καταστάσεων. Sealed interface — για συμβάντα και ενέργειες όπου απαιτείται πολλαπλή υλοποίηση. Value class (Kotlin 1.5+) — ένα περιτύλιγμα για μία τιμή χωρίς επιβάρυνση. Χρησιμοποιείται για type-safe αναγνωριστικά: @JvmInline value class UserId(val id: String).

Συναρτήσεις (extension, inline, higher-order, scope functions)

Extension Function — προσθήκη μεθόδου σε υπάρχουσα κλάση χωρίς κληρονομικότητα. fun String.isEmail(): Boolean. Extension Property — το ίδιο για ιδιότητες (χωρίς backing field). Inline Function — εισαγωγή σώματος συνάρτησης στο σημείο κλήσης — χωρίς επιβάρυνση κλήσης. Χρησιμοποιείται για higher-order συναρτήσεις με lambdas. Higher-Order Function — συνάρτηση που δέχεται ή επιστρέφει άλλη συνάρτηση. Scope Functions — πέντε συναρτήσεις για εργασία με το πλαίσιο αντικειμένου: let, run, with, apply, also.

Scope Functions

let — πλαίσιο it, επιστρέφει αποτέλεσμα lambda. Χρησιμοποιείται για null-safe κλήσεις (?.let {}). apply — πλαίσιο this, επιστρέφει πλαίσιο. Για διαμόρφωση αντικειμένου. run — πλαίσιο this, επιστρέφει αποτέλεσμα lambda. Για υπολογισμούς με πλαίσιο. also — πλαίσιο it, επιστρέφει πλαίσιο. Για παρενέργειες (καταγραφή). with — δεν είναι extension, πλαίσιο this, επιστρέφει αποτέλεσμα lambda. Για ομάδα λειτουργιών σε αντικείμενο. Lambda — ανώνυμη συνάρτηση. Destructuring Declaration — αποσυσκευασία data class σε μεταβλητές: val (name, age) = person.

Inline + reified

Inline function με reified — ο μόνος τρόπος διατήρησης γενικού τύπου στη JVM. Χρησιμοποιείται για: type-safe builders (Gson.fromJson<T>()), έλεγχο τύπου (is T), λήψη κλάσης (T::class). Crossinline και Noinline — τροποποιητές για παραμέτρους lambda σε inline συναρτήσεις. crossinline — απαγορεύει το non-local return, noinline — απαγορεύει το inlining συγκεκριμένης lambda. Η IT Sectr συνιστά inline + reified μόνο κατά την εργασία με τύπους; για συνηθισμένες higher-order συναρτήσεις, το inline μπορεί να αυξήσει το μέγεθος bytecode.

Coroutines (Coroutine Builder, Dispatchers, Scope)

Coroutines — ελαφριά νήματα για ασύγχρονο προγραμματισμό. Δεν μπλοκάρουν το νήμα — αναστέλλονται (suspend). suspend function — συνάρτηση που μπορεί να ανασταλεί χωρίς μπλοκάρισμα νήματος. Μπορεί να κληθεί μόνο από coroutine ή άλλη suspend function.

CoroutineScope

CoroutineScope — ένα πεδίο για coroutines. Περιέχει CoroutineContext (Job + Dispatcher). lifecycleScope — για Activity/Fragment (επίγνωση κύκλου ζωής). viewModelScope — για ViewModel (αυτόματη ακύρωση στο onCleared()). GlobalScope — καθολικό πεδίο (μην χρησιμοποιείται σε παραγωγή — διαρροές μνήμης). Dispatchers: Dispatchers.Main (UI), Dispatchers.IO (δίκτυο/δίσκος), Dispatchers.Default (CPU-intensive), Dispatchers.Unconfined (δεν συνιστάται). launch — εκκινεί coroutine: Job. async — εκκινεί με αποτέλεσμα: Deferred<T>. runBlocking — μπλοκάροντας γέφυρα. withContext — αλλάζει Dispatcher μέσα σε suspend function.

kotlin
// Παράδειγμα coroutines: φόρτωση δεδομένων σε ViewModel
class MainViewModel : ViewModel() {
    private val _state = MutableStateFlow<UiState>(UiState.Loading)
    val state: StateFlow<UiState> = _state.asStateFlow()

    fun loadData() {
        viewModelScope.launch {
            _state.value = UiState.Loading
            try {
                val data = withContext(Dispatchers.IO) {
                    repository.fetchData()
                }
                _state.value = UiState.Success(data)
            } catch (e: Exception) {
                _state.value = UiState.Error(e.message)
            }
        }
    }
}

// Παράλληλα αιτήματα με async
suspend fun loadCombinedData(): CombinedData = coroutineScope {
    val users = async(Dispatchers.IO) { api.getUsers() }
    val posts = async(Dispatchers.IO) { api.getPosts() }
    CombinedData(users.await(), posts.await())
}

viewModelScope.launch — τυπική εκκίνηση coroutine σε ViewModel. withContext(Dispatchers.IO) — εναλλαγή σε νήμα IO για αίτημα δικτύου. Dispatchers καθορίζουν σε ποιο νήμα-pool εκτελείται το coroutine. Η IT Sectr συνιστά viewModelScope για ViewModel και lifecycleScope για Activity/Fragment.

Προηγμένες δυνατότητες (reified, destructuring, lateinit/lazy)

reified — τροποποιητής τύπου σε inline συναρτήσεις. Επιτρέπει τη χρήση τύπου: T::class, is T, as T. Χωρίς reified, τα generics στη JVM διαγράφονται (type erasure). inline fun + reified — ισχυρός συνδυασμός για type-safe API. Destructuring Declaration — val (x, y) = point. Λειτουργεί για data class και τύπους με componentN(). typealias — ψευδώνυμο τύπου: typealias Callback = (String) -> Unit. lateinit — καθυστερημένη αρχικοποίηση var (για dependency injection). Μη ασφαλές νήματος. lazy — τεμπέλικη αρχικοποίηση val (προεπιλογή ασφαλής νήματος). lazy(LazyThreadSafetyMode.NONE) — χωρίς συγχρονισμό. Extension function και Extension property — προσθήκη λειτουργικότητας χωρίς κληρονομικότητα. Η Kotlin είναι μια γλώσσα όπου οι extension functions λύνουν το 90% των βοηθητικών εργασιών.

Εκχωρημένες Ιδιότητες

Delegated Properties — εκχώρηση getter/setter σε άλλο αντικείμενο. Τυπικοί εκχωρητές: lazy, observable, vetoable, map. Προσαρμοσμένος εκχωρητής μέσω τελεστών getValue/setValue. by — λέξη-κλειδί εκχώρησης: val name by lazy { loadName() }. Οι εκχωρημένες ιδιότητες αποτελούν τη βάση για εκχωρητές ViewModel (by viewModels()). Η IT Sectr συνιστά lazy για καθυστερημένη αρχικοποίηση και Delegates.observable για παρακολούθηση αλλαγών.

Δυνατότητα Περιγραφή Παράδειγμα
reifiedΔιατήρηση γενικού τύπου σε inlineinline fun <reified T> parse(): T
destructuringΑποσυσκευασία data classval (name, age) = person
typealiasΨευδώνυμο τύπουtypealias Orders = List<Order>
lateinitΚαθυστερημένη αρχικοποίηση varlateinit var adapter: Adapter
lazyΤεμπέλικη αρχικοποίηση valval config by lazy { load() }
delegatedΕκχώρηση ιδιοτήτωνvar x by Delegates.observable(0)

reified — για type-safe API. lazy — για καθυστερημένη φόρτωση. delegated properties — για επαναχρησιμοποίηση λογικής ιδιοτήτων. Η IT Sectr συνιστά την εκμάθηση όλων αυτών των δυνατοτήτων για αποτελεσματική ανάπτυξη Kotlin.

Flow και StateFlow

Flow — ψυχρή ασύγχρονη ροή δεδομένων στην Kotlin. Εκπέμπει τιμές κατ' απαίτηση του συλλέκτη. StateFlow — θερμό Flow με μία τρέχουσα τιμή. Χρησιμοποιείται σε ViewModel για UI State. SharedFlow — θερμό Flow για συμβάντα (εφάπαξ συμβάντα). flowOf, asFlow — δημιουργία Flow από συλλογές. catch, retry, debounce — τελεστές. stateIn, shareIn — μετατροπή ψυχρού Flow σε θερμό. Η IT Sectr συνιστά StateFlow για UI State και SharedFlow για συμβάντα (Snackbar, πλοήγηση).

kotlin
class SearchViewModel : ViewModel() {
    private val _query = MutableStateFlow("")
    val suggestions: StateFlow<List<String>> = _query
        .debounce(300)
        .filter { it.length >= 2 }
        .flatMapLatest { repository.search(it) }
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())

    fun onQueryChanged(query: String) {
        _query.value = query
    }
}

Σειριοποίηση (kotlinx.serialization, Parcelize)

kotlinx.serialization — βιβλιοθήκη Kotlin για σειριοποίηση JSON. @Serializable — σχολιασμός. @SerialName — προσαρμοσμένο όνομα πεδίου. Υποστηρίζει: JSON, CBOR, ProtoBuf. Parcelize — @Parcelize για Android Parcelable (χωρίς χειροκίνητη υλοποίηση). Gson vs Moshi vs kotlinx: kotlinx.serialization — Kotlin-first, ασφαλής μεταγλώττισης, χωρίς αντανάκλαση. Moshi — σχολιασμοί + codegen. Η IT Sectr συνιστά kotlinx.serialization για νέα έργα και Moshi για υπάρχοντα.

kotlin
@Serializable
data class ApiResponse<T>(
    val success: Boolean,
    @SerialName("data") val data: T? = null,
    val error: String? = null
)

@Serializable
data class User(
    val id: Int,
    val name: String,
    val email: String
)

// Αποσειριοποίηση
val json = Json { ignoreUnknownKeys = true }
val response = json.decodeFromString<ApiResponse<List<User>>>(jsonString)
println("Users: ${response.data?.size ?: 0}")

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

Ποια είναι η διαφορά μεταξύ data class και sealed class;

data class — για δεδομένα (αυτόματη δημιουργία equals/hashCode/copy). sealed class — για ιεραρχία τύπων (έλεγχος σε when). sealed interface — ίδιο με πολλαπλή κληρονομικότητα.

Τι είναι οι scope functions στην Kotlin;

let, run, with, apply, also. Διαφέρουν ανάλογα με το πλαίσιο (it vs this) και την τιμή επιστροφής (result vs context). let — ασφάλεια null, apply — διαμόρφωση, also — παρενέργειες.

Τι είναι το CoroutineScope και ποιοι τύποι υπάρχουν;

CoroutineScope — πεδίο coroutines. lifecycleScope — για Activity, viewModelScope — για ViewModel. GlobalScope — δεν συνιστάται.

Τι είναι το reified στην Kotlin;

reified — διατήρηση τύπου σε inline συναρτήσεις. Επιτρέπει T::class και is T. Λειτουργεί μόνο με inline συναρτήσεις.

Τι είναι τα coroutine builders: launch, async, runBlocking;

launch — χωρίς αποτέλεσμα. async — με αποτέλεσμα (Deferred). runBlocking — μπλοκάροντας γέφυρα για main/test. withContext — αλλαγή Dispatcher.

Σύνοψη

  • data class — για μοντέλα. sealed class — για καταστάσεις. object — για singleton.
  • Scope functions: let (ασφαλές null), apply (διαμόρφωση), run (υπολογισμοί), also (καταγραφή).
  • Coroutines: launch (fire-and-forget), async (με αποτέλεσμα), withContext (αλλαγή Dispatcher).
  • viewModelScope — πρότυπο για ViewModel. lifecycleScope — για Activity/Fragment.
  • reified — type-safe inline συναρτήσεις. lateinit — DI, lazy — τεμπέλικη αρχικοποίηση.
  • Extension functions — προσθέστε λειτουργικότητα χωρίς κληρονομικότητα.
  • Dispatchers: Main (UI), IO (δίκτυο/δίσκος), Default (CPU). Επιλέξτε το σωστό.

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

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

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