# 17. Hafta — Sınıf ve Nesne Kullanımı

## Bu hafta ne yapacağız?

Bir öğrencinin numarası, adı, sınıfı ve notları birbiriyle ilişkilidir. Bu bilgileri ayrı değişkenlerde tutmak yerine tek bir `Ogrenci` nesnesinde birleştireceğiz. Ardından nesneleri bir listede gösterecek, seçilen öğrencinin ayrıntısını açacak ve yeni not eklenince ortalamanın kendiliğinden güncellenmesini sağlayacağız.

Haftanın ikinci uygulamasında aynı düşünceyi bir sınıf kitaplığına taşıyacağız. Kitapları modelleyecek, ödünç verme/iade işlemini gerçekleştirecek ve yalnız raftaki kitapları filtreleyeceğiz.

## Kazanımlar

- Dart dilinde sınıf, nesne, alan, kurucu metot, metot ve `getter` kavramlarını kullanma
- Bir modele ait veriyi ve davranışı aynı sınıfta toplama
- Model nesnelerini `List` içinde saklama ve `ListView` ile gösterme
- Kullanıcı işlemi sonucunda modeli değiştirip arayüzü `setState` ile yenileme
- Hesaplanan bir değeri `getter` ile her zaman güncel üretme

## 1. Ders — Öğrenci modelini oluşturma

Önce uygulamanın veri yapısını kuruyoruz. `required` anahtar sözcüğü, bir öğrenci oluştururken temel bilgilerin unutulmasını engeller. `ortalama` ve `durum` ayrıca saklanmaz; notlardan hesaplanır. Böylece yeni not eklendiğinde eski bir ortalama değerini güncelleme zorunluluğu doğmaz.

```dart
class Ogrenci {
  Ogrenci({
    required this.numara,
    required this.ad,
    required this.sinif,
    required this.notlar,
  });

  final int numara;
  final String ad;
  final String sinif;
  final List<int> notlar;

  double get ortalama =>
      notlar.fold<int>(0, (toplam, not) => toplam + not) / notlar.length;

  String get durum => ortalama >= 85
      ? 'Çok iyi'
      : ortalama >= 70
          ? 'Başarılı'
          : ortalama >= 50
              ? 'Gelişiyor'
              : 'Destek gerekli';

  void notEkle(int not) => notlar.add(not.clamp(0, 100));
}
```

Burada:

- `final` alanlar nesnenin kimlik bilgilerini korur.
- `notlar` listesinin içine yeni değer eklenebilir.
- `fold`, listedeki notları toplayıp ortalamayı hesaplar.
- `clamp(0, 100)`, eklenecek notu geçerli aralıkta tutar.

## 2. Ders — Nesne listesini hazırlama

Her satır aynı veri yapısını kullandığı için üç ayrı değişken grubu yerine üç `Ogrenci` nesnesi oluşturuyoruz.

```dart
final ogrenciler = [
  Ogrenci(
    numara: 1124,
    ad: 'Ece Yılmaz',
    sinif: '11/B',
    notlar: [78, 92, 86],
  ),
  Ogrenci(
    numara: 1131,
    ad: 'Mert Kaya',
    sinif: '11/B',
    notlar: [66, 74, 81],
  ),
  Ogrenci(
    numara: 1140,
    ad: 'Zeynep Ak',
    sinif: '11/B',
    notlar: [91, 88, 95],
  ),
];
```

## 3. Ders — Listeyi ekrana bağlama

`ListView.builder`, listedeki her model için bir öğrenci kartı üretir. Kartın `onTap` olayı seçilen nesneyi `secili` değişkenine aktarır.

```dart
ListView.builder(
  shrinkWrap: true,
  itemCount: ogrenciler.length,
  itemBuilder: (context, index) {
    final ogrenci = ogrenciler[index];
    return ListTile(
      title: Text(ogrenci.ad),
      subtitle: Text('${ogrenci.sinif} • ${ogrenci.notlar.length} değerlendirme'),
      trailing: Text(ogrenci.ortalama.toStringAsFixed(1)),
      onTap: () => setState(() => secili = ogrenci),
    );
  },
)
```

## 4. Ders — Modeli değiştirme ve sonucu yenileme

Seçilen öğrenciye 100 puan eklendiğinde `notEkle` metodu modeli değiştirir. `setState`, kartı yeniden oluşturur; ortalama ve durum `getter` üzerinden güncel notlarla tekrar hesaplanır.

```dart
FilledButton.icon(
  onPressed: () => setState(() => secili!.notEkle(100)),
  icon: const Icon(Icons.playlist_add_check),
  label: const Text('100 puan ekle'),
)
```

Ece Yılmaz'ın ilk ortalaması `(78 + 92 + 86) / 3 = 85,3` olur. 100 puan eklendiğinde sonuç `(78 + 92 + 86 + 100) / 4 = 89,0` olarak yenilenir.

## Çalışan uygulamanın gerçek ekranı

Aşağıdaki görüntü, Flutter widget testi sırasında uygulama çalıştırılıp Ece Yılmaz seçildikten ve 100 puan eklendikten sonra alınmıştır.

![Öğrenci Modeli gerçek Flutter ekranı](../../screenshots/week-17-adapted.png)

## Özgün uygulama — Sınıf Kitaplığı

Şimdi bilgiyi farklı bir günlük yaşam problemine uyguluyoruz. Her kitap ISBN, ad, yazar, sayfa sayısı ve ödünç durumu taşır.

```dart
class Kitap {
  Kitap({
    required this.isbn,
    required this.ad,
    required this.yazar,
    required this.sayfa,
    this.odunc = false,
  });

  final String isbn;
  final String ad;
  final String yazar;
  final int sayfa;
  bool odunc;

  String get durum => odunc ? 'Ödünç verildi' : 'Rafta';
  void oduncDurumunuDegistir() => odunc = !odunc;
}
```

Ödünç verme düğmesi modeldeki `odunc` değerini değiştirir. Filtre açıkken görünür liste, yalnız `odunc == false` olan kitaplardan oluşturulur.

```dart
final gorunenKitaplar = sadeceRafta
    ? kitaplar.where((kitap) => !kitap.odunc).toList()
    : kitaplar;
```

![Sınıf Kitaplığı gerçek Flutter ekranı](../../screenshots/week-17-original.png)

## Uygulama görevleri

### Kolay — Ders modeli

`Ders` adında bir sınıf oluşturun. Ders adı, haftalık saat ve öğretmen alanlarını tanımlayın. Üç ders nesnesini kartlar hâlinde gösterin.

### Orta — Servis yolcu listesi

`Yolcu` modelinde ad, durak ve araca binip binmediğini tutun. Düğmeyle durumu değiştirin; araçtaki öğrenci sayısını ekranda gösterin.

### İleri — Kantin stok sistemi

`Urun` modelinde ad, fiyat ve stok bilgisi tutun. Satış metodunda stok sıfırsa işlem yapılmasını engelleyin. Toplam stok değeri ve satış tutarını hesaplayan getter'lar ekleyin.

## Kontrol listesi

- Model sınıfı arayüz kodundan ayrı ve anlaşılır mı?
- Kurucu metotta zorunlu alanlar `required` olarak işaretlendi mi?
- Hesaplanan değerler gereksiz yere ayrıca saklanmak yerine getter ile mi üretiliyor?
- Modeldeki değişiklik `setState` içinde yapılarak ekrana yansıtılıyor mu?
- Liste boşken ve çok elemanlıyken görünüm test edildi mi?

## Geri bildirim ve çözüm erişimi

Önce kendi uygulamanızı gönderin. Geri bildirimden sonra **İpucunu göster** bölümü yalnız yaklaşımı ve kontrol noktalarını açıklar; **Örnek çözümü göster** bölümü ise çalışan projenin gerçek `lib/main.dart` kodunu açar. Aynı bölümdeki indirme bağlantısından projeyi çevrim dışı çalıştırmak için tam kaynak paketini indirebilirsiniz.

## Kaynak projeler

- Konu uygulaması: `05 - Modelleme ve Listeler/Uygulamalar/Uygulama-17-Öğrenci Modeli`
- Özgün uygulama: `05 - Modelleme ve Listeler/Uygulamalar/Ozgun-17-Kitaplık Modeli`
