"Szia! Folytatom Ellie leckét a generikus gyógyszerekről. Készen állsz a hallgatásra?"

"Igen."

– Akkor kezdjük.

"Az első dolog, amit tudnod kell, hogy egy osztály metódusainak is lehetnek saját típusparaméterei."

"Tudom."

"Nem, kifejezetten a saját típusparamétereikre gondolok: "

Példa
class Calculator
{
  T add(T a, T b); // Add
  T sub(T a, T b); // Subtract
  T mul(T a, T b); // Multiply
  T div(T a, T b); // Divide
}

"Ezek a típusparaméterek kifejezetten a metódusokra vonatkoznak. Az osztálynak nincsenek paraméterei. Ezeket a metódusokat akár statikusnak is deklarálhatod, és objektum nélkül hívhatod meg."

"Értem. A típusparaméterek lényege a metódusokban ugyanaz, mint az osztályoknál?"

– Igen. De van valami új.

"Mint már tudja, használhat helyettesítő karaktert a típusdeklarációban. Ezután képzelje el a következő helyzetet:"

1. példa
public void doSomething(List<? extends MyClass> list)
{
 for(MyClass object : list)
 {
  System.out.println(object.getState()); // Everything works well here.
 }
}

"De mi van akkor, ha egy új elemet szeretnénk hozzáadni a gyűjteményhez:"

2. példa
public void doSomething(List<? extends MyClass> list)
{
 list.add(new MyClass()); // Error!
}

"A probléma az, hogy általános esetben a doSomething metódus egy olyan Listát kaphat, amelynek elemei nem MyClass objektumok, hanem a MyClass bármely alosztályának objektumai. De ilyen listához nem lehet MyClass objektumokat hozzáadni!"

"Ah. Szóval mit lehet tenni ez ellen?"

"Semmi. Ebben a helyzetben nem tehetsz semmit. Ez azonban gondolkodásra késztette a Java alkotóit. És kitaláltak egy új kulcsszót: szuper ."

"A szintaxis majdnem ugyanúgy néz ki:"

List<? super MyClass> list

De van egy fontos különbség a kiterjesztett és a szuper között.

"«? kiterjeszti a T-t» azt jelenti, hogy az osztálynak T leszármazottjának kell lennie."

""? szuper T" azt jelenti, hogy az osztálynak T elődjének kell lennie."

"Holy Moly. Akkor ezt hol használják?"

A ""? szuper T» akkor használatos, ha egy metódus T objektumok gyűjteményéhez tartozik. Ebben az esetben ez lehet T objektumok gyűjteménye vagy T bármely őse."

"Ah. Az AT objektum hozzárendelhető egy referenciaváltozóhoz, amelynek típusa T bármelyik őse"

"Őszintén szólva, ezt a megközelítést nem használják túl gyakran. Sőt, van egy hiányossága. Például:"

Példák
public void doSomething(List<? super MyClass> list)
{
 for(MyClass object : list) // Error!
 {
  System.out.println(object.getState());
 }
}
public void doSomething(List<? super MyClass> list)
{
 list.add(new MyClass()); // Everything works well here.
}

– Most az első példa nem működik.

"Mivel a lista akár egy List<Object> is lehet (az Object a MyClass legfelső szuperosztálya), lényegében a következő érvénytelen kódot írjuk:"

1. példa
List<Object> list; 

for(MyClass object : list) // Error!
{ 
 System.out.println(object.getState()); 
}

– Értem. Köszönöm az érdekes leckét.

"Szívesen."