C# - Konstruktorok

C# nyelv 19. rész

forráskód letöltése
Osztályok létrehozásánál sok esetben elkerülhetetlen a konstruktorok alkalmazása. Mostani cikkünkben a konstruktorok létrehozásával, azok típusaival és szerepével foglalkozunk részletesebben.
A konstruktort tekinthetjük egy olyan speciális függvénynek, melyben lévő kód akkor fut le, amikor az adott osztályból létrehozunk egy példányt. A konstruktor éppen ezért jól felhasználható olyan esetekben, amikor egy-egy példány létrejöttekor szükséges valamilyen osztályon belüli inicializálást elvégezni, például egy belső változónak kezdeti értéket adni.
A konstruktorok deklarálása nem különbözik egy hagyományos függvény deklarálásától. Amiért még konstruktor lesz belőle az az, hogy neve meg kell egyezzen az osztályának nevével, tehát ha létrehozunk egy Class1 nevű osztályt és abban egy Class1 nevű függvényt, akkor ez a függvény az osztály konstruktora lesz.
Egy osztályon belül több konstruktor is lehet épp úgy, mint ahogy egy függvénynek is több példánya lehet. Ekkor nyilván a függvények paraméter listája kell, hogy különbözzön. Mellékelt példa Class1.cs állományában hozzuk létre a Class1 nevű osztályt. Ebben egy int típusú FA nevű változó van. Az első konstruktornak két paramétere van. FA úgy kap értéket, hogy e két számot összeadjuk.
    public class Class1
    {
      public int FA;
      public Class1(int x, int y)
      {
        FA = x + y;
      }
Ezek után létrehozunk egy másik konstruktort is, de most már csak egy paraméterrel. Ez esetben megfigyelhető még egy érdekesség: a konstruktorhoz nem írunk kódot, ehelyett inkább meghívunk egy másik konstruktort, mely elvégzi a szükséges értékadást FA-nak. Ehhez a this kulcsszót használjuk és paraméterezzük, mintha az egy függvény lenne. Valójában úgy is viselkedik, mert ezzel meghívjuk az első konstruktort, mely két paramétert vár. Elsőként tovább adjuk a kapott z változót, másodikként pedig 100-at, mint egy alapértelmezett értéket.
     public Class1(int z): this (z, 100) 
     {
     }
Továbbiakban létrehozunk egy második osztályt is Class2 névvel, melyet a Class1-ből származtatunk. Itt szintén létrehozunk konstruktort, de kódot most sem adunk meg. Ehelyett felhasználjuk az ős osztályban lévő konstruktort. Tehetjük ezt úgy, hogy a base kulcsszót használjuk és paraméterezzük, mintha ez is egy függvény lenne. Ennek az lesz a hatása, hogy az ős osztályban keresés történik egy olyan konstruktor után, mely két paramétert vár. Mivel ilyen van is, így ez kerül meghívásra. Paramétereinek értéke pedig a Class2 konstruktorának átadott a és b változó kétszerese lesz, így ezek összege kerül végül az FA-ba
    public class Class2: Class1
    {
      public Class2(int x, int y): base(x * 2, y * 2)
      {
      }
    }
Nézzük most miként tudjuk felhasználni ezeket az osztályokat. Létrehozunk a Class1-ből két, míg a Class2-ből egy példányt, mindegyik esetben különböző konstruktort használva.
      protected void button1_Click (object sender, System.EventArgs e)
      {
Az első esetben FA értéke 10 + 1, vagyis 11 kell hogy legyen.
        Class1 c1a = new Class1(10, 1);
A második konstruktornál 1000 + 100 értéke kerül az FA-ba.
        Class1 c1b = new Class1(1000);
Végül a Class2 konstruktort használva 10 * 2 + 1 * 2 kerül FA-ba.
        Class2 c2 = new Class2(10, 1);
Ellenőrzésképpen ki is íratjuk e három osztály FA változójának tartalmát.
        listBox1.Items.Add(c1a.FA.ToString());
        listBox1.Items.Add(c1b.FA.ToString());
        listBox1.Items.Add(c2.FA.ToString());
      }
A konstruktorokkal kapcsolatban azt is tudnunk kell, hogy lehetőségünk van nem csak publikus, hanem privát konstruktorok létrehozására is. Tudjuk azt, hogy egy függvény, ha privát, akkor az kívülről nem érhető el. Így van ez a konstruktor esetében is. Felmerül ez esetben a kérdés, hogy akkor mi értelme van egy konstruktort privátként deklarálni, hiszen ilyenkor képtelenek lennénk elérni azt és így példányt létrehozni az adott osztályból. A válasz is pontosan ez. A lényeg ilyen esetben pont az, hogy meggátoljuk, hogy az osztályból legyen példány létrehozva. Nézzük erre az alábbi kódot:
public class PIValue
{
   private PIValue () {}      
   public static double PI ()
  {
     return 3.14159265358979323846;
   }
}
Ez esetben a PIValue osztályból nem tudunk példányt létrehozni, de ennek amúgy sem lenne értelme, hiszen csak egyetlen statikus függvénye van. Ilyen esetben jól használható a privát konstruktor arra a célra, hogy megakadályozzuk az osztályból történő példány létrehozását.
Még egy érdekes lehetőséget meg kell említenünk a konstruktorokkal kapcsolatban: ez pedig annak lehetősége, hogy konstruktort deklarálhatunk statikusként is. Ebben az esetben úgy tudjuk felhasználni az osztály egy-egy példányát, hogy azokhoz akár változót sem kell deklarálnunk és a new operátort használnunk.
    public class Stat
    {
      public static DateTime FB;
      static Stat()
      {
        FB = DateTime.Now;
      }
    }
Ilyen esetben elegendő csak az osztály nevét leírni és ennek hatására azonnal meghívásra kerül a statikus konstruktor, mely a mi esetünkben értéket ad az FB belső változónak, amelynek értéket rögtön le is kérdezhetjük és kiírhatjuk szintén a ListBox-ba.
listBox1.Items.Add(Stat.FB.ToString());        

C# nyelv cikksorozat