Bölüm 6 — Konu 27: Class Tanımlama, Constructor (Varsayılan, Named, Factory)
Dizi · 26/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
Bölüm 6'ya hoş geldin — Dart'ın nesne yönelimli programlama (OOP) dünyasına giriyoruz. Bu bölüm, Flutter'ın widget mimarisini anlamak için doğrudan temel oluşturacak, çünkü her widget aslında bir class'tır.
Class Nedir?
Bir class, gerçek dünyadaki bir "şeyi" (nesneyi) modellemek için kullanılan bir şablondur — o şeyin özelliklerini (alanlar/fields) ve davranışlarını (metodlar) bir arada tutar.
class Kisi {
String isim = "";
int yas = 0;
void selamVer() {
print("Merhaba, ben $isim, $yas yaşındayım.");
}
}
void main() {
Kisi kisi1 = Kisi(); // nesne (instance) oluşturma
kisi1.isim = "Ahmet";
kisi1.yas = 25;
kisi1.selamVer(); // Merhaba, ben Ahmet, 25 yaşındayım.
}Temel terimler:
- Class (sınıf): Şablonun kendisi (
Kisi) - Instance (nesne/örnek): Class'tan üretilen gerçek bir varlık (
kisi1) - Field (alan): Class'ın sahip olduğu veri (
isim,yas) - Method (metod): Class'ın sahip olduğu davranış/fonksiyon (
selamVer())
Constructor Nedir?
Yukarıdaki örnekte, Kisi() ile bir nesne oluşturduk ve sonra alanları teker teker doldurduk. Bu pratik değil — genelde bir nesneyi oluştururken, değerlerini aynı anda vermek isteriz. Bunu sağlayan yapıya constructor (yapıcı metod) denir.
Varsayılan (Default) Constructor
class Kisi {
String isim;
int yas;
Kisi(String isim, int yas) {
this.isim = isim;
this.yas = yas;
}
void selamVer() {
print("Merhaba, ben $isim, $yas yaşındayım.");
}
}
void main() {
Kisi kisi1 = Kisi("Ahmet", 25);
kisi1.selamVer(); // Merhaba, ben Ahmet, 25 yaşındayım.
}this anahtar kelimesi ne işe yarıyor? Constructor'ın parametreleri (isim, yas) ile class'ın alanları (isim, yas) aynı isme sahip. this.isim, "bu nesnenin isim alanı" anlamına gelir — parametre olan isim'den ayırt etmek için kullanılır. this olmasaydı, isim = isim; yazmak anlamsız olurdu (Dart hangi isim'in kastedildiğini anlayamazdı).
Constructor Kısayolu — this.parametreAdi
Yukarıdaki yazım çok yaygın olduğu için, Dart bunun için özel bir kısayol sunar:
class Kisi {
String isim;
int yas;
Kisi(this.isim, this.yas); // constructor gövdesi bile yok!
void selamVer() {
print("Merhaba, ben $isim, $yas yaşındayım.");
}
}
void main() {
Kisi kisi1 = Kisi("Ahmet", 25);
kisi1.selamVer();
}Kisi(this.isim, this.yas); satırı, bir önceki örnekteki 4 satırlık constructor gövdesiyle tamamen aynı işi yapar. Bu kısayol o kadar yaygındır ki, Dart/Flutter kodunda constructor'ları neredeyse hep bu şekilde yazılmış göreceksin.
Named parametrelerle constructor:
class Kisi {
String isim;
int yas;
Kisi({required this.isim, required this.yas});
}
void main() {
Kisi kisi1 = Kisi(isim: "Ayşe", yas: 30); // named parametre gibi çağrılır
print(kisi1.isim); // Ayşe
}Bölüm 5'te öğrendiğimiz required ve named parametre kavramları burada doğrudan uygulanıyor — ve bu, Flutter widget constructor'larının neredeyse tamamının yazıldığı şekildir.
Named Constructor — Alternatif Oluşturma Yolları
Bazen bir class'ı birden fazla farklı şekilde oluşturabilmek istersin. Dart, bunun için named constructor sunar:
class Kisi {
String isim;
int yas;
Kisi(this.isim, this.yas); // ana constructor
Kisi.bebek(String isim) : isim = isim, yas = 0; // named constructor
Kisi.bilinmeyen() : isim = "Bilinmiyor", yas = 0; // başka bir named constructor
}
void main() {
Kisi kisi1 = Kisi("Ahmet", 25);
Kisi kisi2 = Kisi.bebek("Yeni Doğan");
Kisi kisi3 = Kisi.bilinmeyen();
print(kisi2.isim); // Yeni Doğan
print(kisi2.yas); // 0
print(kisi3.isim); // Bilinmiyor
}Sözdizimi: ClassAdı.constructorAdı(parametreler) : alan1 = deger1, alan2 = deger2;
Bu, bir sonraki derste (initializer list) daha detaylı işleyeceğimiz bir sözdizimi — şimdilik "named constructor, class'ı farklı bir isimle ve farklı bir mantıkla oluşturmanın bir yolu" olarak bil.
Daha okunabilir bir named constructor örneği — this kısayoluyla:
class Nokta {
double x;
double y;
Nokta(this.x, this.y);
Nokta.orijin() : x = 0, y = 0; // orijin noktası (0,0) için özel bir yol
}
void main() {
Nokta n1 = Nokta(3, 4);
Nokta n2 = Nokta.orijin();
print("(${n1.x}, ${n1.y})"); // (3.0, 4.0)
print("(${n2.x}, ${n2.y})"); // (0.0, 0.0)
}Named constructor'lar, Flutter'da da çok sık karşına çıkacak — örneğin Text.rich(...) gibi, aynı widget'ı farklı senaryolar için farklı şekillerde oluşturmanı sağlayan yapılar bu prensiple çalışır.
Factory Constructor — Özel Oluşturma Mantığı
Normal bir constructor her zaman yeni bir nesne oluşturur. Ama bazen, oluşturma mantığının daha karmaşık olmasını istersin — örneğin, koşula göre farklı bir alt tip döndürmek, ya da var olan bir nesneyi (yeni oluşturmadan) döndürmek gibi. Bunun için factory constructor kullanılır:
class Sekil {
String tip;
Sekil(this.tip);
factory Sekil.dairesel() {
print("Dairesel şekil oluşturuluyor...");
return Sekil("Daire");
}
factory Sekil.koseli() {
print("Köşeli şekil oluşturuluyor...");
return Sekil("Kare");
}
}
void main() {
Sekil s1 = Sekil.dairesel();
print(s1.tip); // Daire
Sekil s2 = Sekil.koseli();
print(s2.tip); // Kare
}Normal constructor ile factory constructor arasındaki temel fark: Normal constructor, çağrıldığında her zaman yeni bir nesne (this) oluşturmak zorundadır. Factory constructor ise bir fonksiyon gibi davranır — içinde istediğin mantığı çalıştırabilir, var olan bir nesneyi (cache'den) döndürebilir, ya da koşula göre farklı bir alt sınıfın nesnesini döndürebilir. Bu ileri kullanımları (özellikle "singleton" deseni ve alt sınıf döndürme) Bölüm 7'de kalıtımı işledikten sonra çok daha anlamlı hale gelecek — şimdilik factory constructor'ın "oluşturma mantığını özelleştirebileceğin" bir araç olduğunu bilmen yeterli.
Nesne Oluşturma Sözdizimi — Eski vs Yeni
void main() {
// Eski Dart sürümlerinde 'new' anahtar kelimesi zorunluydu
Kisi kisi1 = new Kisi("Ahmet", 25); // hâlâ çalışır ama...
// Modern Dart'ta 'new' opsiyoneldir ve KULLANILMASI ÖNERİLMEZ
Kisi kisi2 = Kisi("Ahmet", 25); // standart, tercih edilen yazım
}
class Kisi {
String isim;
int yas;
Kisi(this.isim, this.yas);
}Modern Dart kod tabanlarında new anahtar kelimesini görmeyeceksin — kaldırılması yönünde topluluk kararı alınmış ve artık gereksiz kabul ediliyor.
🎯 Bu Dersten Çıkarılması Gerekenler
class, bir nesnenin şablonudur;instance(örnek), o şablondan üretilen gerçek bir varlıktır.- Constructor, bir nesneyi oluştururken alanlarını doldurmayı sağlar.
this.alanAdikısayolu, constructor gövdesi yazmadan alanları doğrudan doldurur.- Named constructor (
Kisi.bebek()gibi), aynı class'ı farklı senaryolar için farklı yollarla oluşturmayı sağlar. - Factory constructor, oluşturma mantığını özelleştirmeye (cache, koşullu üretim, alt sınıf döndürme) izin verir.
- Modern Dart'ta
newanahtar kelimesi kullanılmaz.
📝 Ödevler
- [ ] Bir
Kitapsınıfı oluştur (başlık, yazar, sayfa sayısı alanları),this.alankısayolu ile bir constructor yaz. - [ ] Aynı
Kitapsınıfına, named parametreli (requiredile) alternatif bir constructor daha ekle, ikisini de dene. - [ ]
KitapsınıfınaKitap.bosKitap()adında bir named constructor ekle — başlık "Bilinmiyor", yazar "Bilinmiyor", sayfa sayısı 0 olsun. - [ ] Basit bir factory constructor örneği yaz — örneğin bir
Renksınıfı içinRenk.kirmizi(),Renk.mavi()gibi factory constructor'lar tanımla, her biri farklı bir hex değeriyle nesne döndürsün. - [ ] Kendi tanımladığın bir sınıftan 3 farklı nesne oluştur (varsayılan constructor, named constructor, factory constructor kullanarak), her birinin alanlarını yazdır.
Sıradaki konu: Bölüm 6 — Konu 28: Alanlar (Fields), Metodlar, this Kullanımı (Derinlemesine)