Keri sisuni

Objektide loomine

Märksõna new

Klasside põhjal loodud muutujaid nimetatakse objektideks. Kirjanduses kohtab ka oluliselt kohmakamat terminit objekti kohta - klassi instants (class instance). Objektide loomiseks kasutame märksõna new, millele järgneb klassi nimi.

public class Car
{
    public string Model { get; set; }
    public string Manufacturer { get; set; }
}

var car1 = new Car();
var car2 = new Car();

Konstruktorid

Igal klassil on olemas vähemalt üks eriline meetod, mida nimetatakse konstruktoriks (constructor). Konstruktor käivitatakse objekti loomisel. Kui me klassile kontruktorit defineerinud pole, siis luuakse see kompilaatori poolt automaatselt. Eelnevas näites toodud klassile loob kompilaator automaatselt tühja parameetriteta konstruktori, et meil oleks võimalik selle klassi põhjal objekte luua. Oma olemuselt on konstruktor siiski meetod ja järgib meetoditele seatud reegleid.

Eeltoodud klassi võiksime kirjutada ka selliselt:

public class Car
{
    public string Model { get; set; }
    public string Manufacturer { get; set; }

    public Car() // Klassi konstruktor
    {
    }
}

Konstruktor erineb muudest meetoditest selle poolest, et tal puudub tagastatav tüüp (tegelikult võiksime öelda, et konstruktori tagastatav tüüp on sama selle klassiga, kuhu ta kuulub).

Parameetritega konstruktorid

Et konstruktor on lihtsalt üks erisorti meetod, siis võib sellel olla ka parameetreid. Kui klassil on ainult parameetritega konstruktor, siis peame objekti loomisel andma konstruktorile kaasa kõik parameetrite, mida see vajab.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}

var person = new Person("John", "Smith");
using System;

namespace OOP
{
    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public Person(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var person = new Person("Jaan", "Jalgratas");

            Console.Write(person.FirstName);
            Console.Write(" ");
            Console.WriteLine(person.LastName);
        }
    }
}

Pane tähele!

Kui oleme klassile loonud ise vähemalt ühe konstruktori, siis kompilaator meile tühja parameetrite loendiga konstruktorit automaatselt ei loo.

Mitu konstruktorit

Samuti võib olla klassil mitu konstruktorit, mis erinevad teineteisest parameetrite loendi poolest.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Code { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public Person(string firstName, string lastName, string code)
    {
        FirstName = firstName;
        LastName = lastName;
        Code = code;
    }
}

var person1 = new Person("John", "Smith");
var person2 = new Person("Mari-Liis", "Männik", "47302200234");

Toodud näide sobib küll idee edastamiseks, kuid sellega on üks probleem: korduv kood, mida näeme konstruktorites. Korduva koodi vältimiseks kasutatakse tihti sellist trikki nagu constructor chaining. See tähendab seda, et ühes konstruktoris on kood ning teised konstruktorid kutsuvad seda, andes kaasa parameetrite väärtused, mida nad teavad.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Code { get; set; }

    public Person(string firstName,string lastName):this(firstName,lastName,null)
    {
    }

    public Person(string firstName, string lastName, string code)
    {
        FirstName = firstName;
        LastName = lastName;
        Code = code;
    }
}

var person1 = new Person("John", "Smith");
var person2 = new Person("Mari-Liis", "Männik", "47302200234");
using System;

namespace OOP
{
    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Code { get; set; }

        public Person(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }

        public Person(string firstName, string lastName, string code)
        {
            FirstName = firstName;
            LastName = lastName;
            Code = code;
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var people = Person[2];

            people[0] = new Person("Jaan", "Jalgratas");
            people[1] = new Person("Mari-Liis", "Männik", "47302200234");

            foreach(var person in people)
            {
                Console.Write(person.FirstName);
                Console.Write(" ");
                Console.Write(person.LastName);
                Console.Write(" ");
                Console.WriteLine(person.Code);
            }
        }
    }
}

Jäta meelde!

Constructor chaining on üks objekt-orienteeritud disaini häid praktikaid, sest välistab korduva koodi kasutamise konstruktorites.

Objekti initsialiseerija

Klassidel võib olla omadusi, mida konstruktori kaudu klassi ei anta, kuid mida objekti loomisel soovime kohe väärtustada.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
}

var person = new Person();
person.FirstName = "John";
person.LastName = "Dow";
person.Address = "Illinois avenue 139/34";

Selle koodi saame objekti initsialiseerijat (object initializer) kasutades kirjutada ka kompaktsemalt.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Address { get; set; }
}

var person = new Person
{
    FirstName = "John";
    LastName = "Dow";
    Address = "Illinois avenue 139/34";
};

Pane tähele!

Kui tegemist on klassiga, millel on palju omadusi, siis võib objekti initsialiseerija kasutamine hoopis täiendavat segadust tekitada.

Destruktorid

Klassidele loob kompilaator veel ühe erilise meetodi. Selleks on destruktor (destructor), mis kutsutakse välja kui objekt mälust eemaldatakse. Desktruktorid on keerukam teema ning jääb selle aine raamidest välja.

Viited