generics etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
generics etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

29 Ekim 2015 Perşembe

Generics ve Wildcard

Java
Not : Java'da generic konusunu anlamak için Java Generics FAQs - Frequently Asked Questions  yazısına mutlaka bakmak gerekir.

Java'da generic ile kullanılan parametre tiplerine wildcard uygulanabiliyor. Bazı wildcard örnekleri

Collection<?> , List<? extends Number> , Comparator<? super String> and Pair<String,?>
Şimdi bu örneklerin ne olduğuna bakalım

Java'da generics için wildcard ve bound kullanılması ciddi şikayetlere sebep olmuş durumda.

Unbounded Wildcard
Kalıtım hiyerarşisine dikkat etmeyen sınırlandırılmamış wildcard anlamına gelir. Herhangi bir generic tip kullanan nesne, unbounded wildcard ile tanımlanmış nesneye atanabilir. Assignment compatible'dır. İki unbounded wildcard assignment compatible değildir!

ArrayList <?>       anyList    = new ArrayList<Long>();
ArrayList<String> stringList = new ArrayList<String>();
anyList    = stringList;
stringList = anyList;      // error

Nesne Ekleme
unbounded wildcard genellikle okuma işlemi için kullanılır. Örnekte Box sınıfı tipini bilmediği bir nesneyi kabul etmiyor. Ancak null eklenebilir.
Box<?> box = new Box<String>("abc");
box.put("xyz");     // error 
box.put(null);     // ok
Unbounded Wildcard Ne İçin Lazımdır
Tipini bilmediğimiz nesneleri okumak için kullanılır. Örnekte tipini bilmediğimiz listedeki nesneler print ediliyor.
public static void printList(List<?> list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}
Android'den de bir örnek verebiliriz. parent nesnesi AdapterView<?> olarak geçiliyor.
listview.setOnItemClickListener(new AdapterView.OnItemClickListener(){
  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position, long id)
  {....}

Bounded Wildcard
Java
Generics ve Bounded Wildcard yazısına taşıdım.

C#'ta Upper Bound Generics
Generics ve Wildcard yazısına taşıdım.

Sık Yapılan Hatalar
Kalıtım İlişkisi Olmayan Bir Sınıf Kullanmak
Bazen kalıtım kullanan generics kodlarında anlaması zor hata mesajları alınabiliyor. En sık karşılaşılanı
Bound mismatch: The type X is not a valid substitute for the bounded parameter Y of the type Z
gibi bir mesaj. Burada anlatılmaya çalışılan X ve Y arasında beklenen kalıtım ilişkisi olmadığı.

Raw Type Kullanmak
Örnekte  Number'dan türeyen nesneler isteyen bir metod var.
public static void organizeData(java.util.List<? extends Number> c) {
    //operation on the list
}
Bu metod, raw type kullanan bir liste ile çağrılabilir. Bu durumda Uncheked Type Conversion uyarısı alırız.
List newList = new LinkedList<>();
ClassName.organizeData(newList);


2 Şubat 2015 Pazartesi

Generics ve Static Alanlar

Static alan içeren bir sınıfımız olsun
public class SomeClass<T>
{
    public static string SomeField;
}
Her farklı tip için bu static alana yeni bir değer atamak mümkün.
SomeClass<int>.SomeField = "A";
SomeClass<string>.SomeField = "B";

Console.WriteLine(SomeClass<int>.SomeField);    // A
Console.WriteLine(SomeClass<string>.SomeField); // B





3 Şubat 2014 Pazartesi

Generics ve Kalıtım


Alt sınıfta Tekrar Üst Sınıfa Cast Etmek
Bu problem her hangi bir dilde de karşımıza çıkabilir. Probleme verilen genel bir isim var mı bilmiyorum. Ancka çözüm hemen hep aynı oluyor.

Alt sınıf kendisini kullanarak generic bir metodu çağırınca artık üst sınıfın bilgisi kaybedildiği için problem olabiliyor. Bu durumda üst sınıfın bilgisini de alt sınıfa geçmek gerekir. Aşağıdaki örnekte AbstractClass içinden Connection.Update (this) çağrılsaydı Connection sınıfı sadece Abstract class'ı bilecekti.

C#
Aşağıdaki örnekte üst sınıf kendi bilgisini kaybetmeden Connection.Update metoduna geçebiliyor.

abstract class AbstractClass<T>
where T: AbstractClass<T> //restrict T as a child of AbstractClass<T>
{
    bool update()
    {
        Connection.Update<T>(this as T);
    }
}

class Entity : AbstractClass<Entity>
{
}

class Connection
{
    public static void Update<T>(T obj)
    {
        someMethod<T>()
    }
}