# Jenerikler (Generics)

Eğer temel dizi tipi olan `List`'in API belgelerine göz atarsanız, tipin aslında `List<E>` olduğunu göreceksiniz. `<...>` gösterimi, `List`'in bir jenerik (veya parametreli) tip olduğunu belirtir - yani, formal tip parametreleri olan bir tiptir. Genellikle, çoğu tip değişkeni tek harfli isimlere sahiptir, örneğin E, T, S, K ve V gibi.

### **Jenerik Türleri Neden Kullanmalıyız?**

Jenerikler genellikle tip güvenliği için gereklidir, ancak kodunuzun çalışmasına izin vermenin ötesinde daha fazla faydası vardır:

* Doğru jenerik tipleri belirlemek, daha iyi oluşturulmuş kodlara neden olur.
* Jenerikleri kullanarak kod tekrarını azaltabilirsiniz.

Eğer bir listenin sadece dizeleri içermesini istiyorsanız, onu `List<String>` olarak bildirebilirsiniz (bu, "dize listesi" olarak okunur). Bu şekilde, bir dize olmayan bir değeri listeye atamanın muhtemelen bir hata olduğunu, sizin ve diğer programcıların araçlarının tespit edebileceği bir şekilde ifade etmiş olursunuz. İşte bir örnek:

```dart
// Statik analiz: hata
var isimler = <String>[];
isimler.addAll(['Seth', 'Kathy', 'Lars']);
isimler.add(42); // Hata
```

Jenerikleri kullanmanın bir başka nedeni de kod tekrarını azaltmaktır. Jenerikler, birçok tür arasında tek bir arayüzü ve uygulamayı paylaşmanıza olanak tanırken hala statik analiz avantajlarından faydalanmanıza olanak tanır. Örneğin, bir nesneyi önbelleğe alma arayüzü oluşturduğunuzu varsayalım:

```dart
abstract class ObjectCache {
  Object getByKey(String key);
  void setByKey(String key, Object value);
}
```

Bu arayüzün string özel bir versiyonunu istediğinizi fark ederseniz, başka bir arayüz oluşturabilirsiniz:

```dart
abstract class StringCache {
  String getByKey(String key);
  void setByKey(String key, String value);
}
```

Daha sonra, bu arayüzün bir sayı özel versiyonunu istediğinize karar verirseniz... Fikri anladınız.

Jenerik tipler, tüm bu arayüzleri oluşturmanın zahmetinden sizi kurtarabilir. Bunun yerine, bir tür parametre alan tek bir arayüz oluşturabilirsiniz:

```dart
abstract class Cache<T> {
  T getByKey(String key);
  void setByKey(String key, T value);
}
```

Bu kodda, T stand-in türdür. Bu, geliştiricinin daha sonra tanımlayacağı bir tür olarak düşünebileceğiniz bir yer tutucudur.

### **Toplama Litaralleri Kullanma**

`List`, `Set` ve `Map` literalleri parametreli olabilir. Parametreli literaller, zaten gördüğünüz literaller gibi, ancak açılış parantezinin önüne `<type>` (listeler ve setler için) veya `<keyType, valueType>` (`Maps`) için eklersiniz. İşte tip belirtilmiş literalleri kullanmanın bir örneği:

```dart
var isimler = <String>['Bayram', 'Hidayet', 'Mustafa', 'Yunus', 'Hakan'];
var benzersizIsimler = <String>{'Bayram', 'Hidayet', 'Mustafa', 'Yunus', 'Hakan'};
var sayfalar = <String, String>{
  'index.html': 'Ana Sayfa',
  'robots.txt': 'Web robotları için ipuçları',
  'insanlar.txt': 'Biz insanlarız, makine değiliz'
};
```

### **Kurucularla (Constructors) Parametreli Türleri Kullanma**

Bir veya daha fazla tür belirtmek istediğinizde bir constructor kullanırken, türleri sınıf adından hemen sonra açıkhız (`<...>`) içine koyun. Örneğin:

```dart
var isimSeti = Set<String>.from(isimler);
```

Aşağıdaki kod, tamsayı anahtarları olan ve `Gorunum` türünde değerlere sahip bir harita oluşturur:

```dart
var gorunumler = Map<int, Gorunum>();
```

### **Jenerik Koleksiyonlar ve İçerdikleri Türler**

Dart jenerik tipleri, tür bilgilerini çalışma zamanında taşıdıkları anlamına gelir. Örneğin, bir koleksiyonun türünü test edebilirsiniz:

```dart
var isimler = <String>[];
isimler.addAll(['Bayram', 'Hidayet', 'Mustafa', 'Yunus', 'Hakan']);
print(isimler is List<String>); // true
```

Not: Buna karşılık, Java'da jenerik tipler silinir, bu da jenerik tür parametrelerinin çalışma zamanında kaldırıldığı anlamına gelir. Java'da bir nesnenin bir `List` olup olmadığını test edebilirsiniz, ancak bir `List<String>` olup olmadığını test edemezsiniz.

### **Parametreli Türü Sınırlama**

Generik bir türü uygularken, belirli bir türün alt türü olan argümanları sağlamak isteyebilirsiniz, böylece argümanın belirli bir türün alt türü olması gerekmelidir. Bu, extends kullanarak yapılabilir.

Bir türün null olmayan bir alt tür olduğundan emin olmak için genellikle `extends` kullanılır (varsayılan olarak Object yerine). Örneğin:

```dart
class Foo<T extends Object> {
  // Foo için T'ye sağlanan herhangi bir tür, null olmayan bir alt tür olmalıdır.
}
```

Extends ile başka türler de kullanabilirsiniz. İşte `TemelSinif`'i genişleterek `TemelSinif`'in üyelerinin T türündeki nesnelerde çağrılmasına izin veren bir örnek:

```dart
class Foo<T extends TemelSinif> {
  // Uygulama buraya geliyor...
  String toString() => "Foo<$T>'nin örneği";
}

class Extender extends TemelSinif {...}
```

`TemelSinif` veya alt türlerini genişletmek için şu şekilde kullanabilirsiniz:

```dart
var temelSinifFoo = Foo<TemelSinif>();
var extenderFoo = Foo<Extender>();
```

Ayrıca hiçbir jenerik argüman belirtmek de mümkündür:

```dart
var foo = Foo();
print(foo); // 'Foo<TemelSinif>' örneği
```

Herhangi bir `TemelSinif` olmayan tür belirtmek bir hataya yol açar:

```dart
// Statik analiz: hata
var foo = Foo<Object>();
```

**Jenerik Metotları Kullanma**

Metodlar ve fonksiyonlar da tür argümanlarına izin verir:

```dart
T ilk<T>(List<T> ts) {
  // İlk işlemleri veya hata kontrolünü yapın, sonra...
  T tmp = ts[0];
  // Ek kontrol veya işlemleri yapın...
  return tmp;
}
```

Buradaki jenerik tür parametresi ilk (`<T>`), tür argümanını `T`'yi birkaç yerde kullanmanıza olanak tanır:

* Fonksiyonun dönüş türünde (`T`).
* Bir argümanın türünde (`List<T>`).
* Yerel bir değişkenin türünde (`T tmp`).

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dart.bayramalacam.com/turler-types/jenerikler-generics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
