Személyes eszközök
Keresés

 

A InfoWiki wikiből



Tartalomjegyzék

THIS paraméter

A 'this' (más nyelveken 'self') kulcsszóval a példányszintű metódusokban (beleértve a példányszintű konstruktorokat is) hivatkozhatunk az aktuális példányra. Más szóval a 'this' hordozza az aktuális példány referenciáját.

Ezen 'this' egy láthatatlan paraméterként viselkedik példányszintű metódus esetében. Mintha minden metódus automatikusan megkapná azt egy extra paraméter formájában automatikusan, a hívás helyén megjelölt példány alapján:

class TAuto
{
  protected int aktBenzin;
 
  public void Feltankol(int mennyiseg)
  {
    aktBenzin += mennyiseg;
  }
}
 
// ... főprogram ...
TAuto a = new TAuto();
TAuto b = new TAuto();
a.Feltankol( 10 );
b.Feltankol( 15 );

A fenti kód valójában az alábbi formában létezik (a fordítóprogram automatikusan végzi az átalakítást):

class TAuto
{
  protected int aktBenzin;
 
  public void Feltankol(int mennyiseg, TAuto this)
  {
    this.aktBenzin += mennyiseg;
  }
}
 
// ... főprogram ...
TAuto a = new TAuto();
TAuto b = new TAuto();
TAuto -> Feltankol( 10, a );
TAuto -> Feltankol( 15, b );

Vagyis a példányszintű metódusok esetén a plusz egy paramétert automatikusan írja hozzá a formális paraméterlistához. A 'this' paraméter típusa megegyezik a szóban forgó osztály típusával.

A hívás helyén a példányt, amelyen keresztül a metódust meghívtuk, automatikusan helyezi el az aktuális paraméterlistában, hogy a 'this' paraméter értéke felvehesse annak referenciáját (memóriacímét).

Ha egy példányszintű metódusban valamely példányszintű mezőre hivatkozunk, akkor az elé automatikusan beíródik a 'this.' hivatkozás, jelezvén hogy ez az aktuális példány szóban forgó mezője kell legyen. Ezért lehetséges az, hogy az 'a.Feltankol(...)' esetében az 'a' példány 'aktBenzin' mezője módosul, míg második esetben a 'b' példány megfelelő mezője módosul, a nélkül hogy ezt a metódus belsejében különösebben jeleznünk kellene.


THIS és az osztályszintű metódusok

Ilyen extra paraméter az osztályszintű metódusok (és konstruktor) esetében nyilvánvalóan nincsen, hiszen ezen metódusok hívásához nincs szükség példányokra. A hívásuk osztálynéven keresztül történik meg, vagyis nincs példány, amely ezen extra paraméter értékét definiálhatná az aktuális paraméterlistában.

THIS felhasználása (1)

Mint láthatjuk, a 'this' a háttérben teljesen automatikusan, és logikusan működik, a programozó beavatkozására nincs szükség. Miért fontos akkor ennek ismerete?

Elsősorban azért, mert ez a magyarázata annak (többek között), hogy 'this' nevű paramétert a programozó nem deklarálhat a metódusaihoz. Ilyen nevű paraméter ugyanis már eleve létezik.

Másrészt ha a programozó tudatában van a 'this' létezésének és szerepének, akkor kihasználhatja azt. Elsősorban két esetben szoktuk hasznát venni a 'this' létezésének:

class TAuto
{
  protected int kilometerAllas;
 
  public TAuto(int kilometerAllas)
  {
    // hibás!
    kilometerAllas = kilometerAllas;
  }
}
 
// ... főprogram ...
TAuto a = new TAuto(0);

A fenti kód írásakor a programozó a konstruktor paraméterét ugyanúgy nevezte el, mint a mezőt. A konstruktor belsejében a paraméter értéket próbálja áttölteni a mezőbe, hogy megadja annak kezdőértékét, de ekkor a fordítóprogram már nem fogja érteni, melyik a mező, és melyik a paraméterváltozó név az értékadásban.

Az azonosítók újradeklarálásának szabálya szerint amennyiben egy azonosítót szűkebb érvényességi körrel újradeklarálunk, akkor ezen szűkebb területen ő elfedi a bővebb érvényességi körű azonosítót. A fenti példában a paraméterváltozó szűkebb érvényességi körű mint a mező, ezért a konstruktor belsejében mindkét 'kilometerAllas' azonosító a paraméterváltozót jelöli, vagyis az értékadó utasítás átmásolja a 'kilometerAllas' paraméterváltozó értékét a 'kilometerAllas' paraméterváltozóba. Ez nyilván "nem csinál semmit", értelmetlen és haszontalan, mindössze pár órajelet vesz el a processzortól.

Nyilvánvalóan a hibát a programozó követte el, aki ugyanúgy nevezte el a paraméterváltozót, mint a mezőt. Nyilvánvalóan a problémát megoldja az, ha másképp nevezi el a paraméterváltozót, mint a mezőt:

class TAuto
{
  protected int fKilometerAllas;
 
  public TAuto(int kilometerAllas)
  {
    // helyes
    fKilometerAllas = kilometerAllas;
  }
}
 
// ... főprogram ...
TAuto a = new TAuto(0);

A fenti névadási szokás egy időben jellemző volt a programozókra, a mezők nevét 'f'-el kezdték (f = field = mező). Ugyanakkor nincs szükség erre, ha a programozó ismeri és felhasználja a 'this' paramétert, amely már a példányszintű konstruktorok esetén is működik:

class TAuto
{
  protected int kilometerAllas;
 
  public TAuto(int kilometerAllas)
  {
    // szintén helyes
    this.kilometerAllas = kilometerAllas;
  }
}
 
// ... főprogram ...
TAuto a = new TAuto(0);

A fenti megoldásban a 'this.kilometerAllas' egyértelműen a mezőt jelöli, a 'this' nélküli második 'kilometerAllas' pedig továbbra is a paraméterváltozót. A fenti megoldással gyakran lehet találkozni, hiszen egyrészt a programozó mentesül, hogy eltérő névadást kelljen használnia, másrészt a 'this.' kiírása után a "Visual Studio" azonnal felsorolja a mezők (és metódusok) neveit listaszerűen, ezért használata bizonyos szempontból kényelmes is.

THIS felhasználása (2)

Míg az előző felhasználás nem szükségszerű, addig a most ismertetett felhasználás más módon, mint a 'this' használata - nem megoldható:

class Rendorseg
{
  public static KarambolJelentes(TAuto a, TAuto b)
  {
    // az 'a' és 'b' autók karamboloztak, helyszinelés, stb.
    ...
  }
}
 
class Auto
{
  public void Osszeutkozes(TAuto szembejovo)
  {
    if (sikerulKikerulni(szembejovo)==false)
       Rendorseg.KarambolJelentes(this, szembejovo);
  }
}
// .. főprogram ..
TAuto a= new TAuto("IDE-321","Skoda",75);
TAuto b= new TAuto("BOSS-001","BMW",140);
a.Osszeutkozes(b);

A fenti kódban az látszik, hogy amikor az 'a' autónk összeütközés közelébe kerül

a 'b' autóval, és nem sikerül elkerülni a balesetet, akkor a rendőrség felé
azonnal jelenti a karambolt. Ehhez azonban mindkét, a karambolban részt vevő
autót azonosítani kell. Az egyik autó az rendben van, azt megkaptuk paraméterként,
ő a 'szembejovo', a másik autó viszont saját magunk vagyunk. Saját magunkra pedig
a 'this' segítségével hivatkozhatunk.

A fenti eset elég gyakori: a metódus belsejéből aktiválunk egy másik metódust, akinek

paraméterként át kell adni saját magunkat. Ekkor a 'this' használata nem elkerülhető!


A THIS további jelentései

Megjegyeznénk, hogy a fenti esetek a 'this' kulcsszó metódusok belsejében történő

felhasználási esetére vonatkozik.

De a 'this' kulcsszót használjuk akkor is, amikor egyik példányszintű konstruktorból

egy másik saját osztálybeli példányszintű konstruktort hívunk:

class Teglalap
 {
     public int X;
     public int Y;
     public int Szeles;
     public int Magas;
 
     public Teglalap():this(0,0,10,10) { }
 
     public Teglalap(int aX, int aY, int aSzeles, int aMagas) 
     {
         X = aX;
         Y = aY;
         Szeles = aSzeles;
         Magas = aMagas;
     }
 }

Illetve 'this'-nek kell elneveznünk az indexelő propertyt is:

class String
{
 
 public char this[int index]
 {
   get
   {
      // az 'index'-edik karakter visszaadása
      return .... ;
   }
 }
}
Hernyák Zoltán
A lap eredeti címe: „http://wiki.ektf.hu/wiki/Mp3/ea12
Nézetek
nincs sb_18.217.228.35 cikk