Bölüm 7 — Konu 36: Mixin (`with`)
Dizi · 35/64 Dart Türkçe Tutorial
- Bölüm 1 — Konu 1: Dart Nedir, Nerede Kullanılır, Neden Flutter Bu Dili Seçti
- Bölüm 1 — Konu 2: Ortam Kurulumu (Dart SDK, DartPad, Terminal ile Çalıştırma)
- Bölüm 1 — Konu 3: İlk Program (`main()`, `print()`, Dosya Yapısı)
- Bölüm 1 — Konu 4: Yorum Satırları, Temel Sözdizimi Kuralları
- Bölüm 2 — Konu 5: Değişken Tanımlama — `var`, `final`, `const` Farkı
- Bölüm 2 — Konu 6: Temel Tipler — `int`, `double`, `String`, `bool`
- Bölüm 2 — Konu 7: Tip Çıkarımı (Type Inference) ve Açık Tip Belirtme
- Bölüm 2 — Konu 8: `dynamic` ve `Object` — Ne Zaman Kullanılır, Ne Zaman Kaçınılır
- Bölüm 2 — Konu 9: Null Safety Temelleri (`?`, `!`, `late`'e Giriş)
- Bölüm 3 — Konu 10: Aritmetik, Atama, Karşılaştırma, Mantıksal Operatörler
- Bölüm 3 — Konu 11: `if / else if / else`
- Bölüm 3 — Konu 12: `switch` / `switch expression` (Modern Dart)
- Bölüm 3 — Konu 13: Ternary Operatör, `??`, `??=`, `?.`
- Bölüm 3 — Konu 14: `for`, `while`, `do-while` Döngüleri
- Bölüm 4 — Konu 16: `List` — Oluşturma, Erişim, Temel Metodlar
- Bölüm 4 — Konu 17: `Set` — Benzersiz Eleman Mantığı
- Bölüm 4 — Konu 18: `Map` — Key-Value Yapılar
- Bölüm 4 — Konu 19: Koleksiyon Üzerinde `for-in`, `forEach`
- Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For
- Bölüm 5 — Konu 21: Fonksiyon Tanımlama, Parametreler (Positional, Named, Optional)
- Bölüm 5 — Konu 22: Varsayılan Parametre Değerleri (Derinlemesine)
- Bölüm 5 — Konu 23: Arrow Function (`=>`) Sözdizimi
- Bölüm 5 — Konu 24: Fonksiyonlar Birinci Sınıf Vatandaş — Değişkene Atama, Parametre Olarak Geçme
- Bölüm 5 — Konu 25: Anonim Fonksiyonlar ve Closure Kavramı (Derinlemesine)
- Bölüm 5 — Konu 26: Recursion (Özyineleme)
- Bölüm 6 — Konu 27: Class Tanımlama, Constructor (Varsayılan, Named, Factory)
- Bölüm 6 — Konu 28: Alanlar (Fields), Metodlar, `this` Kullanımı (Derinlemesine)
- Bölüm 6 — Konu 29: Initializer List, Constructor Kısayolları (Derinlemesine)
- Bölüm 6 — Konu 30: Getter / Setter
- Bölüm 6 — Konu 31: Statik Üyeler (`static`)
- Bölüm 7 — Konu 32: Kalıtım (`extends`), `super` Kullanımı
- Bölüm 7 — Konu 33: Metod Override Etme, `@override`
- Bölüm 7 — Konu 34: Soyut Sınıflar (`abstract class`)
- Bölüm 7 — Konu 35: Interface Mantığı (`implements`)
- Bölüm 7 — Konu 36: Mixin (`with`)
- Bölüm 7 — Konu 37: `enum` — Basit ve Gelişmiş (Metotlu Enum'lar)
- Bölüm 8 — Konu 38: `try / catch / finally`, `throw`
- Bölüm 8 — Konu 39: Özel Exception Sınıfları Yazma
- Bölüm 8 — Konu 40: Sound Null Safety Derinlemesine — `late`, `required`, Non-Nullable Varsayılan Davranış
- Bölüm 8 — Konu 41: `assert` ile Geliştirme Zamanı Kontrolleri
- Bölüm 9 — Konu 42: Generic Sınıflar ve Fonksiyonlar
- Bölüm 9 — Konu 43: Generic Sınırlamalar (`<T extends ...>`)
- Bölüm 9 — Konu 44: Dart'ın Built-in Generic Koleksiyonları Nasıl Çalışır
- Bölüm 10 — Konu 45: `Future` Kavramı, `async`/`await`
- Bölüm 10 — Konu 46: `Future.then`, Hata Yönetimi (`catchError`)
- Bölüm 10 — Konu 47: `Stream` Temelleri, `async*`, `yield`
- Bölüm 10 — Konu 48: `StreamController`, Broadcast Stream
- Bölüm 11 — Konu 49: `map`, `where`, `reduce`, `fold`
- Bölüm 11 — Konu 50: `sort`, Custom Comparator ile Sıralama
- Bölüm 11 — Konu 51: Iterable Kavramı Derinlemesine (Lazy Evaluation)
- Bölüm 11 — Konu 52: Cascade Notasyonu (`..`)
- Bölüm 12 — Konu 53: `pubspec.yaml`, pub.dev'den Paket Ekleme
- Bölüm 12 — Konu 54: Kütüphane Oluşturma, `import`/`export`, `part`/`part of`
- Bölüm 12 — Konu 55: Dart'ta Test Yazımı (`test` Paketi, Unit Test Mantığı)
- Bölüm 12 — Konu 56: Extension Methods
- Bölüm 12 — Konu 57: Dart'ın Derleme Modelleri (JIT vs AOT) ve Bunun Flutter'a Etkisi
- Bölüm 13 — Konu 59: Dart 3 Pattern Matching — Records, Destructuring, Sealed Classes, Exhaustive Switch
- Bölüm 13 — Konu 60: `Never` Tipi, `covariant` ve Generic Variance Detayları
- Bölüm 13 — Konu 61: Event Loop Derinlemesine — Microtask Queue vs Event Queue
- Bölüm 13 — Konu 62: Memory Model & Performans — Garbage Collection, `const` Nesnelerin Bellek Avantajı
- Bölüm 13 — Konu 63: Isolate'ler Arası Mesajlaşmanın Maliyeti ve `compute()`'un İç İşleyişi
- Bölüm 13 — Konu 64: FFI (Foreign Function Interface) — C Koduna Erişim
- Bölüm 13 — Konu 65: Sunucu Tarafında Dart — `dart:io`, `shelf` Paketiyle Basit Bir Backend/CLI Aracı Yazma
- Bölüm 13 — Konu 66: Derleyici & Analiz Araçları — `dart analyze`, Custom Lint Kuralları, `build_runner` Mimarisi
İçindekiler 9 başlık
- Mixin Nedir? — extends ile implements Arasında Bir Orta Yol
- mixin Anahtar Kelimesi
- Neden Mixin Var? — Çoklu "Davranış Kaynağı" İhtiyacı
- Mixin vs Kalıtım — Ne Zaman Hangisi?
- on ile Mixin'i Belirli Tiplerle Sınırlama
- Birden Fazla Mixin'de Aynı Metod — Sıralama Önemli
- Gerçek Dünya Örneği — Flutter'da Mixin
- 🎯 Bu Dersten Çıkarılması Gerekenler
- 📝 Ö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ıftanimplements: 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.
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
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:
void main() {
Loglanabilir l = Loglanabilir(); // ❌ HATA! mixin'den doğrudan nesne oluşturulamaz
}Neden Mixin Var? — Çoklu "Davranış Kaynağı" İhtiyacı
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
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.
class Araba with Ucabilir { // ❌ HATA! Araba, Hayvan'dan türemiyor
}Birden Fazla Mixin'de Aynı Metod — Sıralama Önemli
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,
withanahtar kelimesiyle, birden fazla kaynaktan gerçek davranışı (implementasyonu) bir class'a "karıştırmayı" sağlar. mixinanahtar 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
- [ ]
YuzebilirveUcabiliradında iki mixin yaz, bunları birOrdekclass'ınawithile ekle, her iki davranışı da test et. - [ ] Aynı yetenekleri (yüzme, koşma) birbiriyle ilgisiz iki farklı class'a (örn.
InsanveRobot) mixin ile kazandır — kalıtım hiyerarşisi kurmadan. - [ ]
onanahtar 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
extendsveyamixinkullanarak modelle.
Sıradaki konu: Bölüm 7 — Konu 37: enum — Basit ve Gelişmiş (Metotlu Enum'lar)