# Genişletme Türleri (Extension Types)

Genişletme türleri, mevcut bir türü farklı, yalnızca derleme zamanında bir arayüzle saran bir derleme zamanı soyutlamasıdır. Bu soyutlama, statik JavaScript etkileşiminde kritik bir rol oynar çünkü gerçek bir sarmalayıcı nesnenin maliyetini gerektirmeden mevcut bir türün arayüzünü değiştirmek için kullanılabilirler.

Genişletme türleri, temsil türü olarak adlandırılan mevcut bir türle birlikte kullanılır. Bir genişletme türünün arayüzünü tanımlarken, temsil türünün disiplin altına alınmasını sağlarlar. Genişletme türünün arayüzünü tanımlarken, temsil türünün arayüzünden bazı üyeleri yeniden kullanabilir, bazılarını atlayabilir, bazılarını değiştirebilir ve yeni işlevsellik ekleyebilirsiniz.

Aşağıdaki örnek, `int` türünü sadece ID numaraları için anlamlı olan işlemlere izin veren bir genişletme türü oluşturur:

```dart
extension type IdNumber(int id) {
  // 'int' türünün '<' operatörünü genişletir:
  operator <(IdNumber diger) => id < diger.id;
  // '+' operatörünü bildirmez, çünkü toplama ID numaraları için anlamsızdır.
}

void main() {
  // Bir genişletme türünün disiplini olmadan, 'int' ID numaralarını güvensiz işlemlere açar:
  int guvensizId = 42424242;
  guvensizId = guvensizId + 10; // Bu çalışır, ancak ID'ler için izin verilmemeli.

  var guvenliId = IdNumber(42424242);
  guvenliId + 10; // Derleme zamanı hatası: '+' operatörü yok.
  guvensizId = guvenliId; // Derleme zamanı hatası: Yanlış tip.
  guvensizId = guvenliId as int; // Tamam: Temsil türüne run-time dönüşüm.
  guvenliId < IdNumber(42424241); // Tamam: Genişletilmiş '<' operatörü kullanılır.
}
```

> **Not**
>
> Genişletme türleri, sarmalayıcı sınıfların aksine ek bir çalışma zamanı nesnesi oluşturmayı gerektirmez, bu da birçok nesneyi genişletme ihtiyacı olduğunda maliyeti düşürür. Genişletme türleri, statik olarak belirlenmiş yapılar olup çalışma zamanında silinir, bu nedenle maliyet açısından neredeyse sıfır olarak kabul edilebilir.

## Sözdizimi (Syntax)

### Deklarasyon (Declaration)

Yeni bir genişletme türünü tanımlamak için, genişletme türü bildirimi ve bir ad ile temsil türü bildirimi kullanılır:

```dart
extension type E(int i) {
  // İşlemleri tanımla.
}
```

Temsil türü bildirimi `(int i)` ifadesiyle temsil türünü int olarak belirtir ve bu temsil nesnesine referans için i adını tanımlar. Ayrıca, temsil nesnesine erişim sağlamak için i adında bir özel getirici ve E(int i) adında bir varsayılan olmayan kurucu bildirimi de ekler.

Temsil nesnesi, genişletme türü gövdesinde i kullanılarak erişilebilir (veya kurucu içinde `this.i` olarak).

Genişletme türü bildirimleri, sınıf veya genişletme bildirimlerinde olduğu gibi tür parametrelerini içerebilir:

```dart
extension type E<T>(List<T> elemanlar) {
  // ...
}
```

### Yapıcılar (Constructors)

Genişletme türü gövdesinde isteğe bağlı olarak kurucuları bildirebilirsiniz. Temsil bildirimi zaten örtük bir kurucu görevi gördüğü için, adlandırılmış olmayan kurucu yerine kullanılır. Ek olmayan yönlendiren üretilmemiş kurucular, bu nesnenin başlatılmasını sağlar.

```dart
extension type E(int i) {
  E.n(this.i);
  E.m(int j, String foo) : i = j + foo.length;
}

void main() {
  E(4); // Adlandırılmamış kurucu.
  E.n(3); // Adlandırılmış kurucu.
  E.m(5, "Merhaba!"); // Adlandırılmış kurucu ek parametrelerle.
}
```

Veya temsil bildirimi adını taşıyan bir kurucu olabilir ve bu durumda adlandırılmamış kurucu eklenmez:

```dart
extension type const E._(int it) {
  E(): this._(42);
  E.digerAd(this.it);
}

void main2() {
  E();
  const E._(2);
  E.digerAd(3);
}
```

Ya da tamamen bir kurucu gizleyebilir ve aynı özel kurucu sözdizimini sınıflarda kullanabilirsiniz:

```dart
extension type E._(int i) {
  E.fromString(String foo) : i = int.parse(foo);
}
```

### Üyeler (Members)

Genişletme türü gövdesindeki üyeleri bildirerek arayüzü tanımlayabilirsiniz. Genişletme türü üyeleri, metodlar, getter'lar, setter'lar veya operatörler olabilir. non-external instance variables veya abstract üyeleri içeremezler.

```dart
extension type SayiE(int deger) {
  // Operatör:
  SayiE operator +(SayiE diger) =>
      SayiE(deger + diger.deger);
  // Getter:
  SayiE get benimSayim => this;
  // Metod:
  bool gecerliMi() => !deger.isNegative;
}
```

Varsayılan olarak, temsil türünün arayüz üyeleri, genişletme türü arayüzüne doğal olarak dahil edilmez. Bir temsil türü üyesini genişletme türü arayüzüne dahil etmek için, genişletme türü tanımında onu açıkça bildirmelisiniz, örneğin, NumberE'deki '+' operatörü gibi.

### Uygulamak (Implements)

İsterseniz `implements` ifadesini kullanarak uygulamaları dahil edebilirsiniz:

```dart
extension type SayiI(int i) 
  implements int {
  // 'SayiI', 'int' türünün tüm üyelerini çağırabilir,
  // ve burada başka şeyler de bildirebilir.
}
```

Veya temsil türünün bir üst türünü kullanabilirsiniz:

```dart
extension type Sira<T>(List<T> _) implements Iterable<T> {
  // Liste üzerindeki operasyonlar.
}

extension type Kimlik(int _id) implements Object {
  // Uzantı türünü null olamayan yapar.
  static Kimlik? tryParse(String kaynak) => int.tryParse(kaynak) as Kimlik?;
}
```

Aynı temsil türü üzerinde geçerli olan başka bir genişletme türünü de bildirebilirsiniz, bu da size çoklu kalıtımın bir türün üzerinde tekrar kullanılmasına benzer bir etki sağlar:

```dart
extension type const Secenek<T>._(({T deger})? _) { 
  const factory Secenek(T deger) = Deger<T>;
  const factory Secenek.yok() = Yok<T>;
}

extension type const Deger<T>._(({T deger}) _) implements Secenek<T> { 
  const Deger(T deger) : this._((deger: deger));
  T get deger => _.deger;
}

extension type const Yok<T>._(Null _) implements Secenek<Never> {
  const Yok() : this._(null);
}
```

Bu, farklı uzantı türleri arasında işlemleri yeniden kullanmanıza olanak tanır ve çoklu kalıtımın bir türde tekrar kullanılmasına benzer bir etki sağlar.

#### **`@redeclare`**&#x20;

Bir genişletme türü üyesini bildiren ad, sınıflar arasında olduğu gibi bir yeniden bildirim ilişkisi değil, yeniden bildirimdir. Bir genişletme türü üye bildirimi, aynı adı taşıyan bir üst tür üyesini tamamen değiştirir. Bu işlevi aynı fonksiyon için alternatif bir uygulama sağlamak mümkün değildir.

Aynı adı taşıyan bir üst tür üyesini bilerek kullanıyorsanız, derleyiciye bunun gerçekten doğru olduğunu bildirmek için `@redeclare` açıklamasını kullanabilirsiniz. Derleyici, bir adın yanlış yazıldığı durumları size bildirecektir.

```dart
extension type BenimString(String _) implements String {
  // 'String.operator[]'ı değiştirir.
  @yenidenTanimla
  int operator [](int index) => codeUnitAt(index);
}
```

Ayrıca, eğer bir genişletme türü yöntemi bir üst tür üyesini gizliyorsa ve bu gizli birim yanlışlıkla yapılırsa, @redeclare açıklamasını kullanarak derleyiciye bir uyarı vermesini sağlamak için lint annotate\_redeclares'ı etkinleştirebilirsiniz.

## Kullanım (Usage)

Bir genişletme türünü kullanmak için, bir inşa metodu aracılığıyla bir örneği oluşturarak sınıf gibi davranabilirsiniz:

```dart
extension type SayiE(int deger) {
  SayiE operator +(SayiE diger) =>
      SayiE(deger + diger.deger);

  SayiE get sonraki => SayiE(deger + 1);
  bool gecerliMi() => !deger.isNegative;
}

void testE() { 
  var num = SayiE(1);
}
```

Sonra nesne üzerinde sınıf nesneleri gibi üyeleri çağırabilirsiniz.

Genişletme türleri için iki eşit ancak önemli ölçüde farklı ana kullanım durumu vardır:

* Mevcut bir türe genişletilmiş bir arayüz sağlama
* Mevcut bir türe farklı bir arayüz sağlama

### **Mevcut bir türe genişletilmiş bir arayüz sağlama**&#x20;

Bir genişletme türü, temsil türünü uygularken "şeffaf" olarak düşünülebilir, çünkü genişletme türü, temsil türünü "görebilir". Bu, bir genişletme türünün temsil türünün tüm üyelerini (yeniden bildirilmemiş olanlar) çağırabilmesi anlamına gelir. Bu durumda, genişletme türü, temsil türünün arayüzüne genişletilmiş bir arayüz sağlar.

Bu, örneğin, bir üst sınıfın bazı parametrelerinin daha güvenli olacak şekilde yeniden tanımlandığı bir "çoğunlukla şeffaf" bir genişletme türü olabilir.

```dart
extension tipi SayiT(int deger) 
  implements int {
  // 'int' türünün herhangi bir üyesini açıkça bildirmez.
  SayiT get i => this;
}

void main () {
  // Tamam: Şeffaflık, genişletme türü üzerinde 'int' üyelerini çağırmayı sağlar:
  var v1 = SayiT(1); // v1 türü: SayiT
  int v2 = SayiT(2); // v2 türü: int
  var v3 = v1.i - v1;  // v3 türü: int
  var v4 = v2 + v1; // v4 türü: int
  var v5 = 2 + v1; // v5 türü: int
  // Hata: Genişletme türü arayüzü, temsil türü için kullanılamaz
  v2.i;
}
```

Ya da, bir yöntemin bazı parametrelerine daha katı türleri kullanarak veya farklı varsayılan değerlerle adapte edilen bir "çoğunlukla şeffaf" bir genişletme türü olabilir.

### **Mevcut bir türe farklı bir arayüz sağlama**

Şeffaf olmayan (temsil türünü uygulamayan yani implement olmayan) bir genişletme türü, tamamen yeni bir tür olarak ele alınır ve temsil türünün üyelerini açıkça göstermez.

Örneğin, kullanılan genişletme türü, temsil türü olan int'ten tamamen farklı bir tür olarak kabul edilir. Bu durumda, onu int türüne atayamazsınız ve temsil türünün üyelerine açıkça erişemezsiniz.

```dart
void testE() { 
  var num1 = SayiE(1);
  int num2 = SayiE(2); // Hata: 'SayiE' tipi 'int' tipine atanamaz.
  
  num1.gecerli(); // Tamam: Uzantı üye çağrısı.
  num1.negatifMi(); // Hata: 'SayiE' tipi 'int' tipinde 'negatifMi' üyesini tanımlamaz.
  
  var toplam1 = num1 + num1; // Tamam: 'SayiE' tipi '+' işlemini tanımlar.
  var fark1 = num1 - num1; // Hata: 'SayiE' tipi 'int' tipinde '-' üyesini tanımlamaz.
  var fark2 = num1.deger - 2; // Tamam: Referans ile temsil nesnesine erişilebilir.
  var toplam2 = num1 + 2; // Hata: 'int' tipini 'SayiE' tipine atayamazsınız.
  
  List<SayiE> sayilar = [
    SayiE(1), 
    num1.siradaki, // Tamam: 'siradaki' getter'ı 'SayiE' tipini döndürür.
    1, // Hata: 'int' elemanını 'SayiE' tipine atanamaz.
  ];
}
```

Genişletme türlerini kullanırken, bir türün arayüzünü değiştirmek için güçlü bir araçla performans ve kolaylık avantajına sahip olursunuz, ancak temsil türünün arayüzü asla alt türü olmadığı için bir temsil türünü genişletme türüne ihtiyaç duyulan yerde değiş tokuş yapamazsınız.

## Tür İle İlgili Hususlar (Type Considerations)

Genişletme türleri, derleme zamanında bir sarma yapısıdır. Çalışma zamanında, genişletme türünün hiçbir izi yoktur. Herhangi bir tür sorgusu veya benzeri çalışma zamanı operasyonları, temsil türü üzerinde çalışır.

Bu, genişletme türlerini güvensiz bir soyutlama yapar, çünkü her zaman çalışma zamanında temsil türünü bulabilir ve altındaki nesneye erişebilirsiniz.

Dinamik tür testleri (e is T), dönüşümler (e as T) ve diğer çalışma zamanı tür sorguları (switch (e) ... veya if (e case ...)) tümü temsil nesnesine değerlendirilir ve bu nesnenin çalışma zamanı türüne karşı kontrol eder. Bu durum, e'nin statik türü bir genişletme türü olduğunda ve genişletme türüne karşı test edildiğinde geçerlidir (case MyExtensionType(): ...).

```dart
void main() {
  var n = SayiE(1);

  // 'n'nin çalışma zamanı türü, temsil türü 'int' olarak değerlendirilir.
  if (n is int) print(n.deger); // 1 yazdırır.

  // 'n' üzerinde çalışma zamanında 'int' metotları kullanabiliriz.
  if (n case int x) print(x.toRadixString(10)); // 1 yazdırır.
  switch (n) {
    case int(:var isEven): print("$n (${isEven ? "çift" : "tek"})"); // 1 (tek) yazdırır.
  }
}
```

Benzer şekilde, eşleşen değerin statik türü bu örnekte genişletme türüdür:

```dart
void main() {
  int i = 2;
  if (i is SayiE) print("Bu"); // 'Bu' yazdırır.
  if (i case SayiE v) print("değer: ${v.deger}"); // 'değer: 2' yazdırır.
  switch (i) {
    case SayiE(:var value): print("değer: $value"); // 'değer: 2' yazdırır.
  }
}
```

Genişletme türlerini kullanırken bu özelliği akılda bulundurmak önemlidir. Her zaman genişletme türünün derleme zamanında var olduğunu ve önemli olduğunu, ancak derleme sırasında silindiğini unutmayın.

Bir ifade, genişletme türü E ve statik türü R olarak çalışma zamanında R türündeki bir nesne olacaktır. Hatta tür kendisi de silinir; List\<E>, çalışma zamanında tam olarak List\<R> ile aynı şeydir.

Başka bir deyişle, gerçek bir sarma sınıfı bir sarılı nesneyi kapsayabilirken, bir genişletme türü yalnızca sarılı nesnenin derleme zamanındaki bir görünümüdür. Gerçek bir sarma daha güvenlidir, ancak genişletme türleri size sarma nesnelerini önlemek için bir seçenek sunar, bu da bazı senaryolarda performansı büyük ölçüde artırabilir.


---

# 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/siniflar-ve-nesneler-classes-and-objects/genisletme-turleri-extension-types.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.
