↑↓ seç · Enter aç · Esc kapat

Mutlu Tekin
Mutlu Tekin
← Yazılar

Bölüm 7 — Konu 36: Mixin (`with`)

3 dk okuma #dart
Dizi · 35/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 9 başlık
  1. Mixin Nedir? — extends ile implements Arasında Bir Orta Yol
  2. mixin Anahtar Kelimesi
  3. Neden Mixin Var? — Çoklu "Davranış Kaynağı" İhtiyacı
  4. Mixin vs Kalıtım — Ne Zaman Hangisi?
  5. on ile Mixin'i Belirli Tiplerle Sınırlama
  6. Birden Fazla Mixin'de Aynı Metod — Sıralama Önemli
  7. Gerçek Dünya Örneği — Flutter'da Mixin
  8. 🎯 Bu Dersten Çıkarılması Gerekenler
  9. 📝 Ödevler

Mixin Nedir? — extends ile implements Arasında Bir Orta Yol

Önceki iki derste iki kavram gördük:

  • extends: davranışı devralır ama sadece tek bir üst sınıftan
  • implements: birden fazla "sözleşmeye" uyabilir ama davranış devralmaz, her şeyi yeniden implemente etmen gerekir

Peki ya "birden fazla kaynaktan davranış devralmak" istersen? İşte tam burada mixin devreye giriyor — mixin, birden fazla class'tan davranışı (implementasyonu) bir class'a "karıştırmanı" (mix etmeni) sağlar.

dart
mixin Yuzebilir {
  void yuz() {
    print("Yüzüyorum");
  }
}

mixin Kosabilir {
  void kos() {
    print("Koşuyorum");
  }
}

class Insan with Yuzebilir, Kosabilir {
  // hiçbir metodu implemente etmedik ama HER İKİSİNİ de kullanabiliyoruz!
}

void main() {
  Insan insan = Insan();
  insan.yuz(); // Yüzüyorum — Yuzebilir'den geldi
  insan.kos(); // Koşuyorum — Kosabilir'den geldi
}

Dikkat et: Insan class'ı, yuz() veya kos() metodlarını hiç yazmadı, ama ikisini de kullanabiliyor — çünkü with anahtar kelimesi, mixin'lerin gerçek implementasyonunu (davranışını) class'a "karıştırıyor" (mix ediyor). Bu, implements'ten temel farkı: implements sadece imzayı devralır ve seni implemente etmeye zorlar, with ise gerçek çalışan kodu doğrudan devralır — tıpkı extends gibi.

mixin Anahtar Kelimesi

dart
mixin Loglanabilir {
  void logYaz(String mesaj) {
    print("[LOG] $mesaj");
  }
}

mixin, class tanımlamaya benzer ama özel bir amaç için tasarlanmıştır — doğrudan nesne oluşturmak için değil, başka class'lara davranış "karıştırmak" için kullanılır:

dart
void main() {
  Loglanabilir l = Loglanabilir(); // ❌ HATA! mixin'den doğrudan nesne oluşturulamaz
}

Neden Mixin Var? — Çoklu "Davranış Kaynağı" İhtiyacı

dart
class Ordek with Yuzebilir, Kosabilir {
  void ses() => print("Vak vak!");
}

class Balik with Yuzebilir {
  void ses() => print("...(balıklar sessizdir)");
}

class Atlet with Kosabilir {
  void ses() => print("Nefes nefese");
}

void main() {
  Ordek().yuz();  // Yüzüyorum
  Ordek().kos();  // Koşuyorum
  Balik().yuz();  // Yüzüyorum
  Atlet().kos();  // Koşuyorum
}

Bu örnek, mixin'in asıl gücünü gösteriyor: Ordek, Balik, Atlet — bunların hiçbiri birbirinin alt sınıfı değil (ortak bir üst sınıfları yok, olmasına da gerek yok) ama hepsi ihtiyaç duydukları davranışları (yüzme, koşma) mixin'lerden "karıştırarak" kazanabiliyorlar. Eğer bunu extends ile yapmaya çalışsaydık, tuhaf ve mantıksız bir kalıtım hiyerarşisi kurman gerekirdi (örneğin "YuzebilirVeKosabilirHayvan" gibi devasa, gereksiz bir üst sınıf).

Mixin vs Kalıtım — Ne Zaman Hangisi?

Senaryo Kullan
"X, bir Y'dir" ilişkisi var (Kedi bir Hayvan'dır) extends
"X, Y yapabilir" yeteneği var (Ördek yüzebilir) mixin (with)
Birden fazla bağımsız yetenek kazandırmak istiyorsun mixin (birden fazla, virgülle)
Sadece bir tip sözleşmesi istiyorsun, davranış değil implements

Bu ayrım önemlidir: kalıtım (extends), "is-a" (bir X'tir) ilişkisini modellemeli; mixin ise "can-do" (X yapabilir) yeteneğini modellemelidir. Bir Kus sınıfının Hayvan'dan extends etmesi mantıklıdır (bir kuş, bir hayvandır) — ama "uçabilme" yeteneğini bir mixin (with Ucabilir) olarak modellemek daha doğrudur, çünkü uçma, sadece kuşlara özgü değildir (yarasalar da uçar, ama yarasa bir kuş değildir).

on ile Mixin'i Belirli Tiplerle Sınırlama

dart
class Hayvan {
  String isim;
  Hayvan(this.isim);
}

mixin Ucabilir on Hayvan { // sadece Hayvan (veya alt sınıfı) olan class'lara uygulanabilir
  void uc() {
    print("$isim uçuyor"); // Hayvan'ın 'isim' alanına erişebiliyor!
  }
}

class Kus extends Hayvan with Ucabilir {
  Kus(String isim) : super(isim);
}

void main() {
  Kus kus = Kus("Kartal");
  kus.uc(); // Kartal uçuyor
}

on Hayvan ifadesi, bu mixin'in sadece Hayvan'dan türeyen class'lara uygulanabileceğini belirtir. Bu sayede, mixin içinde Hayvan'ın alanlarına (isim gibi) güvenle erişebiliyoruz — çünkü Dart, bu mixin'i kullanan her class'ın kesinlikle bir Hayvan olacağını garanti ediyor.

dart
class Araba with Ucabilir { // ❌ HATA! Araba, Hayvan'dan türemiyor
}

Birden Fazla Mixin'de Aynı Metod — Sıralama Önemli

dart
mixin A {
  void selamVer() => print("A'dan selam");
}

mixin B {
  void selamVer() => print("B'den selam");
}

class Ornek with A, B {} // B, A'dan SONRA geliyor

void main() {
  Ornek().selamVer(); // B'den selam — SONRAKİ mixin öncelikli
}

Eğer birden fazla mixin aynı isimde bir metod tanımlarsa, sonuncusu (en sağda/altta yazılan) kazanır. Bu, mixin'leri virgülle sıralarken dikkat etmen gereken bir detaydır — sıralama, hangi davranışın "üstün geleceğini" belirler.

Gerçek Dünya Örneği — Flutter'da Mixin

Mixin'ler, Flutter'da da yaygın olarak kullanılır — örneğin bir widget'a animasyon yeteneği kazandırmak için SingleTickerProviderStateMixin gibi mixin'ler with ile eklenir (bunu Flutter tutorial'ında animasyon bölümünde detaylı göreceksin). Şimdiden bu deseni tanıman, ileride "neden bu class'a with ile bir şey ekleniyor" sorusuna hazırlıklı olmanı sağlayacak.


🎯 Bu Dersten Çıkarılması Gerekenler

  • Mixin, with anahtar kelimesiyle, birden fazla kaynaktan gerçek davranışı (implementasyonu) bir class'a "karıştırmayı" sağlar.
  • mixin anahtar kelimesiyle tanımlanır, doğrudan nesne oluşturulamaz.
  • extends, "is-a" (bir şeydir) ilişkisini; mixin ise "can-do" (yapabilir) yeteneğini modellemelidir.
  • on TipAdı ile bir mixin'in sadece belirli bir tipten türeyen class'lara uygulanabilmesi sağlanabilir.
  • Birden fazla mixin aynı metodu tanımlarsa, sıralamada sonraki mixin öncelikli olur.

📝 Ödevler

  • [ ] Yuzebilir ve Ucabilir adında iki mixin yaz, bunları bir Ordek class'ına with ile ekle, her iki davranışı da test et.
  • [ ] Aynı yetenekleri (yüzme, koşma) birbiriyle ilgisiz iki farklı class'a (örn. Insan ve Robot) mixin ile kazandır — kalıtım hiyerarşisi kurmadan.
  • [ ] on anahtar kelimesiyle bir mixin'i belirli bir üst sınıfa bağla, o mixin'i uygunsuz bir class'a uygulamayı deneyip hatayı gözlemle.
  • [ ] İki mixin'de aynı isimli bir metod tanımla, bunları farklı sıralarda bir class'a ekleyip hangisinin "kazandığını" gözlemle.
  • [ ] Kendi senaryonu düşün — "is-a" ilişkisi mi yoksa "can-do" yeteneği mi olduğuna karar ver, buna göre extends veya mixin kullanarak modelle.

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