↑↓ seç · Enter aç · Esc kapat

Mutlu Tekin
Mutlu Tekin
← Yazılar

Bölüm 7 — Konu 37: `enum` — Basit ve Gelişmiş (Metotlu Enum'lar)

3 dk okuma #dart
Dizi · 36/64 Dart Türkçe Tutorial
  1. Bölüm 1 — Konu 1: Dart Nedir, Nerede Kullanılır, Neden Flutter Bu Dili Seçti
  2. Bölüm 1 — Konu 2: Ortam Kurulumu (Dart SDK, DartPad, Terminal ile Çalıştırma)
  3. Bölüm 1 — Konu 3: İlk Program (`main()`, `print()`, Dosya Yapısı)
  4. Bölüm 1 — Konu 4: Yorum Satırları, Temel Sözdizimi Kuralları
  5. Bölüm 2 — Konu 5: Değişken Tanımlama — `var`, `final`, `const` Farkı
  6. Bölüm 2 — Konu 6: Temel Tipler — `int`, `double`, `String`, `bool`
  7. Bölüm 2 — Konu 7: Tip Çıkarımı (Type Inference) ve Açık Tip Belirtme
  8. Bölüm 2 — Konu 8: `dynamic` ve `Object` — Ne Zaman Kullanılır, Ne Zaman Kaçınılır
  9. Bölüm 2 — Konu 9: Null Safety Temelleri (`?`, `!`, `late`'e Giriş)
  10. Bölüm 3 — Konu 10: Aritmetik, Atama, Karşılaştırma, Mantıksal Operatörler
  11. Bölüm 3 — Konu 11: `if / else if / else`
  12. Bölüm 3 — Konu 12: `switch` / `switch expression` (Modern Dart)
  13. Bölüm 3 — Konu 13: Ternary Operatör, `??`, `??=`, `?.`
  14. Bölüm 3 — Konu 14: `for`, `while`, `do-while` Döngüleri
  15. Bölüm 4 — Konu 16: `List` — Oluşturma, Erişim, Temel Metodlar
  16. Bölüm 4 — Konu 17: `Set` — Benzersiz Eleman Mantığı
  17. Bölüm 4 — Konu 18: `Map` — Key-Value Yapılar
  18. Bölüm 4 — Konu 19: Koleksiyon Üzerinde `for-in`, `forEach`
  19. Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For
  20. Bölüm 5 — Konu 21: Fonksiyon Tanımlama, Parametreler (Positional, Named, Optional)
  21. Bölüm 5 — Konu 22: Varsayılan Parametre Değerleri (Derinlemesine)
  22. Bölüm 5 — Konu 23: Arrow Function (`=>`) Sözdizimi
  23. Bölüm 5 — Konu 24: Fonksiyonlar Birinci Sınıf Vatandaş — Değişkene Atama, Parametre Olarak Geçme
  24. Bölüm 5 — Konu 25: Anonim Fonksiyonlar ve Closure Kavramı (Derinlemesine)
  25. Bölüm 5 — Konu 26: Recursion (Özyineleme)
  26. Bölüm 6 — Konu 27: Class Tanımlama, Constructor (Varsayılan, Named, Factory)
  27. Bölüm 6 — Konu 28: Alanlar (Fields), Metodlar, `this` Kullanımı (Derinlemesine)
  28. Bölüm 6 — Konu 29: Initializer List, Constructor Kısayolları (Derinlemesine)
  29. Bölüm 6 — Konu 30: Getter / Setter
  30. Bölüm 6 — Konu 31: Statik Üyeler (`static`)
  31. Bölüm 7 — Konu 32: Kalıtım (`extends`), `super` Kullanımı
  32. Bölüm 7 — Konu 33: Metod Override Etme, `@override`
  33. Bölüm 7 — Konu 34: Soyut Sınıflar (`abstract class`)
  34. Bölüm 7 — Konu 35: Interface Mantığı (`implements`)
  35. Bölüm 7 — Konu 36: Mixin (`with`)
  36. Bölüm 7 — Konu 37: `enum` — Basit ve Gelişmiş (Metotlu Enum'lar)
  37. Bölüm 8 — Konu 38: `try / catch / finally`, `throw`
  38. Bölüm 8 — Konu 39: Özel Exception Sınıfları Yazma
  39. Bölüm 8 — Konu 40: Sound Null Safety Derinlemesine — `late`, `required`, Non-Nullable Varsayılan Davranış
  40. Bölüm 8 — Konu 41: `assert` ile Geliştirme Zamanı Kontrolleri
  41. Bölüm 9 — Konu 42: Generic Sınıflar ve Fonksiyonlar
  42. Bölüm 9 — Konu 43: Generic Sınırlamalar (`<T extends ...>`)
  43. Bölüm 9 — Konu 44: Dart'ın Built-in Generic Koleksiyonları Nasıl Çalışır
  44. Bölüm 10 — Konu 45: `Future` Kavramı, `async`/`await`
  45. Bölüm 10 — Konu 46: `Future.then`, Hata Yönetimi (`catchError`)
  46. Bölüm 10 — Konu 47: `Stream` Temelleri, `async*`, `yield`
  47. Bölüm 10 — Konu 48: `StreamController`, Broadcast Stream
  48. Bölüm 11 — Konu 49: `map`, `where`, `reduce`, `fold`
  49. Bölüm 11 — Konu 50: `sort`, Custom Comparator ile Sıralama
  50. Bölüm 11 — Konu 51: Iterable Kavramı Derinlemesine (Lazy Evaluation)
  51. Bölüm 11 — Konu 52: Cascade Notasyonu (`..`)
  52. Bölüm 12 — Konu 53: `pubspec.yaml`, pub.dev'den Paket Ekleme
  53. Bölüm 12 — Konu 54: Kütüphane Oluşturma, `import`/`export`, `part`/`part of`
  54. Bölüm 12 — Konu 55: Dart'ta Test Yazımı (`test` Paketi, Unit Test Mantığı)
  55. Bölüm 12 — Konu 56: Extension Methods
  56. Bölüm 12 — Konu 57: Dart'ın Derleme Modelleri (JIT vs AOT) ve Bunun Flutter'a Etkisi
  57. Bölüm 13 — Konu 59: Dart 3 Pattern Matching — Records, Destructuring, Sealed Classes, Exhaustive Switch
  58. Bölüm 13 — Konu 60: `Never` Tipi, `covariant` ve Generic Variance Detayları
  59. Bölüm 13 — Konu 61: Event Loop Derinlemesine — Microtask Queue vs Event Queue
  60. Bölüm 13 — Konu 62: Memory Model & Performans — Garbage Collection, `const` Nesnelerin Bellek Avantajı
  61. Bölüm 13 — Konu 63: Isolate'ler Arası Mesajlaşmanın Maliyeti ve `compute()`'un İç İşleyişi
  62. Bölüm 13 — Konu 64: FFI (Foreign Function Interface) — C Koduna Erişim
  63. Bölüm 13 — Konu 65: Sunucu Tarafında Dart — `dart:io`, `shelf` Paketiyle Basit Bir Backend/CLI Aracı Yazma
  64. Bölüm 13 — Konu 66: Derleyici & Analiz Araçları — `dart analyze`, Custom Lint Kuralları, `build_runner` Mimarisi
Dizinin sayfası →
İçindekiler 11 başlık
  1. Basit Enum
  2. Enum ile switch — Exhaustiveness (Hatırlatma)
  3. Enum Üzerinde Gezinme — values
  4. index — Enum Değerinin Sırası
  5. Gelişmiş Enum — Alanlar ve Constructor ile (Dart 2.17+)
  6. Enum'a Metod Ekleme
  7. Pratik Bir Örnek — Gün İsimleri ve Haftasonu Kontrolü
  8. Enum ile Interface Implemente Etme (İleri Bir Not)
  9. 🎯 Bu Dersten Çıkarılması Gerekenler
  10. 📝 Ödevler
  11. 🏁 Bölüm 7 Tamamlandı!

Bölüm 7'nin son konusundayız. enum (enumeration/sabit listesi), sınırlı sayıda, önceden bilinen değerlerden birini temsil eden özel bir tiptir.

Basit Enum

dart
enum TrafikIsigi { kirmizi, sari, yesil }

void main() {
  TrafikIsigi isik = TrafikIsigi.kirmizi;
  print(isik); // TrafikIsigi.kirmizi
  print(isik.name); // kirmizi — sadece ismi
}

Neden String yerine enum kullanılır?

dart
// ❌ Kötü pratik — String ile "durum" temsil etmek
String isikDurumu = "kirmizi";
isikDurumu = "morrr"; // yazım hatası! Ama derleyici bunu YAKALAYAMAZ

// ✅ İyi pratik — enum ile
TrafikIsigi isik = TrafikIsigi.kirmizi;
// isik = TrafikIsigi.morrr; // ❌ DERLEME HATASI! Böyle bir değer yok

enum, olası tüm değerleri derleme zamanında sabitler — geçersiz bir değer atamaya çalıştığında (yazım hatası gibi), Dart bunu anında yakalar. String ile aynı şeyi yapmaya çalışsaydın, hata ancak çalışma zamanında (belki hiç) fark edilirdi.

Enum ile switch — Exhaustiveness (Hatırlatma)

Bölüm 3'te kısaca önizlemesini gördüğümüz konuyu şimdi tam bağlamıyla pekiştirelim:

dart
enum TrafikIsigi { kirmizi, sari, yesil }

String eylemBelirle(TrafikIsigi isik) {
  return switch (isik) {
    TrafikIsigi.kirmizi => "Dur",
    TrafikIsigi.sari => "Hazırlan",
    TrafikIsigi.yesil => "Geç",
  };
}

void main() {
  print(eylemBelirle(TrafikIsigi.kirmizi)); // Dur
}

default (_) yazmadık çünkü tüm enum değerlerini kapsadık — Dart bunu doğrular. Eğer enum'a yeni bir değer eklenirse (örneğin turuncu), bu switch derleme zamanında eksik (non-exhaustive) olarak işaretlenir — böylece unutkanlıktan kaynaklı hatalar baştan engellenir.

Enum Üzerinde Gezinme — values

dart
enum Mevsim { ilkbahar, yaz, sonbahar, kis }

void main() {
  for (var mevsim in Mevsim.values) {
    print(mevsim.name);
  }
  // ilkbahar
  // yaz
  // sonbahar
  // kis
}

EnumAdi.values, o enum'un tüm değerlerini bir liste olarak verir — tüm olası durumlar üzerinde döngü kurmak istediğinde kullanışlıdır.

index — Enum Değerinin Sırası

dart
enum Mevsim { ilkbahar, yaz, sonbahar, kis }

void main() {
  print(Mevsim.ilkbahar.index); // 0
  print(Mevsim.yaz.index);      // 1
  print(Mevsim.kis.index);      // 3
}

Her enum değeri, tanımlandığı sıraya göre otomatik bir index (0'dan başlayan) alır.

Gelişmiş Enum — Alanlar ve Constructor ile (Dart 2.17+)

Modern Dart, enum'lara alan, constructor ve metod eklemene izin verir — bu, enum'ları çok daha güçlü hale getirir:

dart
enum Gezegen {
  merkur(kutle: 3.3, yaricap: 2439),
  venus(kutle: 4.8, yaricap: 6051),
  dunya(kutle: 5.9, yaricap: 6371);

  final double kutle;   // milyar kg cinsinden (basitleştirilmiş)
  final double yaricap; // km cinsinden

  const Gezegen({required this.kutle, required this.yaricap}); // enum constructor'ı HER ZAMAN const olmalı
}

void main() {
  print(Gezegen.dunya.kutle);   // 5.9
  print(Gezegen.dunya.yaricap); // 6371.0
}

Kritik kural: Enum constructor'ları her zaman const olmalıdır — çünkü enum değerleri, Bölüm 2'de öğrendiğimiz const mantığına uygun şekilde, derleme zamanında sabitlenen, tekil (singleton) nesnelerdir. Her Gezegen.dunya referansı, aynı, tek bir nesneye işaret eder.

Enum'a Metod Ekleme

dart
enum Gezegen {
  merkur(kutle: 3.3, yaricap: 2439),
  venus(kutle: 4.8, yaricap: 6051),
  dunya(kutle: 5.9, yaricap: 6371);

  final double kutle;
  final double yaricap;

  const Gezegen({required this.kutle, required this.yaricap});

  double get yogunlukOrani => kutle / yaricap; // getter — Bölüm 6'yı hatırla!

  String bilgiVer() => "Kütle: $kutle, Yarıçap: $yaricap"; // normal metod
}

void main() {
  print(Gezegen.dunya.bilgiVer());       // Kütle: 5.9, Yarıçap: 6371.0
  print(Gezegen.dunya.yogunlukOrani);    // hesaplanmış değer
}

Bu, Bölüm 6'da öğrendiğimiz her şeyin (constructor, alan, getter, metod) enum'lar için de geçerli olduğunu gösteriyor — modern Dart'ta enum, aslında sınırlı sayıda sabit nesnesi olan özel bir class gibi düşünülebilir.

Pratik Bir Örnek — Gün İsimleri ve Haftasonu Kontrolü

dart
enum Gun {
  pazartesi, sali, carsamba, persembe, cuma, cumartesi, pazar;

  bool get haftaSonuMu => this == Gun.cumartesi || this == Gun.pazar;
}

void main() {
  print(Gun.cuma.haftaSonuMu);        // false
  print(Gun.cumartesi.haftaSonuMu);   // true

  for (var gun in Gun.values) {
    print("${gun.name}: ${gun.haftaSonuMu ? "Haftasonu" : "Haftaiçi"}");
  }
}

Bu örnek, Bölüm 1'in ödevlerinde vaat ettiğimiz "gün isimlerini tutan ve haftasonu olup olmadığını döndüren metoda sahip enum" örneğinin tam çözümü — artık bunu gerçek anlamıyla yazabiliyorsun.

Enum ile Interface Implemente Etme (İleri Bir Not)

Modern Dart'ta enum'lar implements de kullanabilir (bir üst sınıfın sözleşmesine uyabilir) — bu, Bölüm 13'te sealed class ve pattern matching konusuna geldiğimizde daha da anlamlı hale gelecek bir özellik. Şimdilik sadece bu kapının açık olduğunu bilmen yeterli.


🎯 Bu Dersten Çıkarılması Gerekenler

  • enum, sınırlı ve önceden bilinen değerleri temsil eder; String ile aynı işi yapmaya çalışmaktan çok daha güvenlidir (derleme zamanı kontrolü sağlar).
  • EnumAdi.values, tüm enum değerlerini bir liste olarak verir; .index, değerin sırasını verir; .name, ismini string olarak verir.
  • switch ile kullanıldığında, tüm değerler kapsandığında default gerekmez — derleyici eksik durumları yakalar.
  • Modern Dart'ta enum'lara alan, constructor (her zaman const), getter ve metod eklenebilir — enum, aslında sınırlı sayıda sabit nesnesi olan özel bir class gibidir.

📝 Ödevler

  • [ ] HaftaGunu adında basit bir enum tanımla, values ile tüm günleri yazdır, .index ve .name özelliklerini kullan.
  • [ ] Bir enum ve bunu kullanan exhaustive bir switch expression yaz (default kullanmadan), sonra enum'a yeni bir değer ekleyip derleyicinin seni nasıl uyardığını gözlemle.
  • [ ] Alanlı ve constructor'lı bir enum yaz (örn. Meyve — isim ve kalori alanlarıyla), en az 3 değer tanımla.
  • [ ] Bu enum'a bir getter ekle (örn. dusukKalorili — kalorisi belirli bir eşiğin altındaysa true dönsün).
  • [ ] Gun enum örneğindeki gibi, kendi enum'una bir metod veya getter ekleyerek pratik bir kontrol mekanizması (örn. tatil günü mü, mesai saati mi) yaz.

🏁 Bölüm 7 Tamamlandı!

Nesne yönelimli programlamanın ileri konularını tamamladık: kalıtım, override, soyut sınıflar, interface'ler, mixin'ler ve gelişmiş enum'lar. Bu, Dart'ın OOP tarafında artık gerçekten sağlam bir temele sahip olduğun anlamına geliyor — ve bu bilgi, Flutter'da widget hiyerarşisini, StatelessWidget/StatefulWidget ayrımını ve birçok tasarım desenini anlamak için doğrudan kullanılacak.

Sıradaki durak Bölüm 8 — Hata Yönetimi & Null Safety Derinleşme: try/catch/finally, özel exception sınıfları yazma ve null safety'nin daha ileri detaylarıyla devam edeceğiz.