"Merhaba, Amigo!"
"Merhaba Ellie!"
"Bugün, Rishi ve ben size jenerik ilaçlar hakkında her şeyi anlatacağız."
"Bekle, sanırım neredeyse her şeyi zaten biliyorum."
"Hemen hemen her şey, ama her şey değil."
"Gerçekten mi? Tamam, dinlemeye hazırım."
"Öyleyse başlayalım."
"Java'da jenerikler, tür parametreleri olan sınıflardır."
"Jeneriklerin neden icat edildiğine gelince, koddaki yorumlara bakın:"
ArrayList stringList = new ArrayList();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // Add a number to the list
for(Object o: stringList)
{
String s = (String) o; // There will be an exception here when we get to the integer
}
Generics kullanarak sorunu nasıl çözebilirim:
ArrayList<String> stringList = new ArrayList<String>();
stringList.add("abc"); // Add a string to the list
stringList.add("abc"); // Add a string to the list
stringList.add( 1 ); // There will be a compilation error here
for(Object o: stringList)
{
String s = (String) o;
}
"Bu kod derlenmeyecek ve yanlış veri türünün eklenmesinden kaynaklanan hata derleme sırasında fark edilecek."
"Evet, bunu zaten biliyorum."
"Tamam, güzel. Tekrar, öğrenmenin anasıdır."
"Ancak Java'nın yaratıcıları jenerikler yaratırken biraz tembeldi. Parametrelerle tam teşekküllü tipler yapmak yerine, kaygan bir optimizasyonda kaydılar. Gerçekte, jeneriklere tip parametreleri hakkında herhangi bir bilgi eklemediler. Bunun yerine, tüm derleme sırasında sihir oluşur."
List<String> strings = new ArrayList<String>();
strings.add("abc");
strings.add("abc");
strings.add( 1); // Compilation error
for(String s: strings)
{
System.out.println(s);
}
List strings = new ArrayList();
strings.add((String)"abc");
strings.add((String)"abc");
strings.add((String) 1); // Compilation error
for(String s: strings)
{
System.out.println(s);
}
"Bu harika."
"Evet, ancak bu yaklaşımın bir yan etkisi var. Tür parametreleri hakkında hiçbir bilgi genel bir sınıf içinde saklanmaz. Bu yaklaşım daha sonra tür silme olarak bilinmeye başlandı ."
"Başka bir deyişle, tür parametreleri olan kendi sınıfınız varsa, onlar hakkındaki bilgileri sınıfın içinde kullanamazsınız."
class Zoo<T>
{
ArrayList<T> pets = new ArrayList<T>();
public T createAnimal()
{
T animal = new T();
pets.add(animal)
return animal;
}
}
class Zoo
{
ArrayList pets = new ArrayList();
public Object createAnimal()
{
Object animal = new ???();
pets.add(animal)
return animal;
}
}
"Derleme sırasında, tüm parametre türleri Object ile değiştirilir. Ve sınıfın içinde kendisine iletilen tür hakkında hiçbir bilgi yoktur."
"Evet, katılıyorum, bu en iyisi değil."
"O kadar korkutucu değil. Bu sorunu nasıl aşacağını sana daha sonra anlatacağım."
Ama dahası var. Java, tür parametreleri için bir üst tür belirtmenize izin verir. Bunun için extends anahtar sözcüğü kullanılır. Örneğin:
class Zoo<T extends Cat>
{
T cat;
T getCat()
{
return cat;
}
void setCat (T cat)
{
this.cat = cat;
}
String getCatName()
{
return this.cat.getName();
}
}
class Zoo
{
Cat cat;
Cat getCat()
{
return cat;
}
void setCat(Cat cat)
{
this.cat = cat;
}
String getCatName()
{
return this.cat.getName();
}
}
"İki gerçeğe dikkat edin:"
"İlk olarak, herhangi bir türü parametre olarak iletemezsiniz - yalnızca bir Cat'i veya Cat'i miras alan bir sınıfı iletebilirsiniz."
"İkincisi, Zoo sınıfının içinde, T türündeki değişkenler artık Cat sınıfının yöntemlerini çağırabilir. Sağdaki sütun nedenini açıklıyor (çünkü T olan her yerde Cat yerine geçecek)"
"Evet. Tip bağımsız değişkeni olarak Cat'in veya Cat'in bir alt sınıfının iletildiğini söylersek, T tipinin her zaman Cat sınıfının yöntemlerine sahip olacağından eminiz."
"Pekala, bu zekice."
GO TO FULL VERSION