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:

// 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:

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:

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:

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:

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:

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

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:

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:

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:

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

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

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

Jenerik Metotları Kullanma

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

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).

Last updated