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:
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:
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:
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.
Veya temsil bildirimi adını taşıyan bir kurucu olabilir ve bu durumda adlandırılmamış kurucu eklenmez:
Ya da tamamen bir kurucu gizleyebilir ve aynı özel kurucu sözdizimini sınıflarda kullanabilirsiniz:
Ü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.
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:
Veya temsil türünün bir üst türünü kullanabilirsiniz:
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:
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
@redeclare
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.
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:
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
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.
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.
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(): ...).
Benzer şekilde, eşleşen değerin statik türü bu örnekte genişletme türüdü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.
Last updated