Objektno-orjentisano programiranje

Vežbe 2

this

Objekti su nosioci aktivnosti, međutim kako može postojati više objekata iste klase nema potrebe na više mesta čuvati jedan te isti kod. Kod je izdvojen u poseban deo memorije. Objekti čuvaju samo podatke, ne čuvaju kod metoda, već samo adresu gde se nalazi kod u memoriji. Kako onda metoda zna za koji objekat treba da bude pozvana? Taj problem je rešen tako što se prilikom poziva metoda šalje implicitni parametar this, koji sadrži referencu na objekat koji je pozvan.


Primer 2.1

class Krug {
    double poluprecnik;

    double dajPovrsinu() {
        return 3.14 * poluprecnik * poluprecnik;
    }

    public static void main(String[] args) {
        Krug krug = new Krug();
        krug.poluprecnik = 10;
        double povrsina = krug.dajPovrsinu();
    }
}

Prilikom prevođenja potis metoda dajPovrsinu() izgleda ovako: dajPovrsinu(Krug this).

Prilikom prevođenja poziv metoda krug.dajPovrsinu() izgleda ovako: krug.dajPovrsinu(krug).


this i atributi

this se takođe koristi i za pristup atributima unutar klase. this možemo a i ne moramo da navodimo unutar klase.

this možemo da iskoristimo da rešimo problem kada se argument konstruktora zove isto kao i atribut klase.


Primer 2.2

class Krug {
    double poluprecnik;

    Krug() {

    }

    Krug(double polupecnik) {
        this.poluprecnik = poluprecnik;
    }

    double dajPovrsinu() {
        return 3.14 * this.poluprecnik * this.poluprecnik;
    }

    public static void main(String[] args) {
        Krug krug = new Krug();
        krug.poluprecnik = 10;
        double povrsina = krug.dajPovrsinu();
    }
}

Ukoliko bi izostavili this unutar konstruktora Krug(double polupecnik) vrednost ne bi bila dodeljena atributu poluprecnik već argumentu konstruktora poluprecnik.


this()

U Javi, kao i u C-u je moguće pozivati jednu funkciju unutar druge. Isto to važi i za overload-ovane metode i konstruktore.


Primer 2.3

class OverloadDemo {

  void test() {
    System.out.println("No parameters");
  }

  void test(int a) {
    test();
    System.out.println("a: " + a);
  }

  void test(int a, int b) {
    test(a);
    System.out.println("a and b: " + a + " " + b);
  }

  double test(double a) {
    System.out.println("double a: " + a);
    return a * a;
  }
}

Kako možemo da pozovemo neki konstruktor unutar nekog drugog konstruktora u okviru iste klase?


Primer 2.4

public class Cube
{
  int length;
  int breadth;
  int height;

  public int getVolume() {
    return (length * breadth * height);
  }

  Cube() {
    length = 10;
    breadth = 15;
    height = 5;
    System.out.println("Constructor with no parameters");
  }

  
  Cube(int l, int b) {
    length = l;
    breadth = b;
    height = 10;
    System.out.println("Constructor with two parameters");
  }

  Cube(int l, int b, int h) {
    length = l;
    breadth = b;
    height = h;
    System.out.println("Constructor with three parameters");
  }

  public static void main(String[] args) {
    Cube cubeObj1, cubeObj2;
    cubeObj1 = new Cube();
    cubeObj2 = new Cube(10, 20, 30);
    System.out.println("Volume of Cube1 is : " + cubeObj1.getVolume());
    System.out.println("Volume of Cube2 is : " + cubeObj2.getVolume());
  }
}

Ako bi unutar konstruktora Cube() hteli da pozovemo konstruktor Cube(int l, int b, int h) sa Cube(10, 15, 5), kompajler bi ovaj poziv tretirao kao poziv metode a ne poziv drugog konstruktora. Ukoliko bi ispred ovog poziva stajao operator new onda bi se kreirao novi objekat i opet ne bi postigli ono što nam je bio cilj. Zbog toga se koristi this(). Poziv jednog konstruktora unutar drugog konstruktora iste klase sa this() mora biti prva linija koda u drugom konstruktoru.


Primer 2.5

public class Cube
{
  int length;
  int breadth;
  int height;

  public int getVolume() {
    return (length * breadth * height);
  }

  Cube() {
    this(10, 15, 5); // Cube(int l, int b, int h)
    System.out.println("Constructor with no parameters");
  }

  
  Cube(int l, int b) {
    this(l, b, 10); // Cube(int l, int b, int h)
    System.out.println("Constructor with two parameters");
  }

  Cube(int l, int b, int h) {
    length = l;
    breadth = b;
    height = h;
    System.out.println("Constructor with three parameters");
  }

  public static void main(String[] args) {
    Cube cubeObj1, cubeObj2;
    cubeObj1 = new Cube();
    cubeObj2 = new Cube(10, 20, 30);
    System.out.println("Volume of Cube1 is : " + cubeObj1.getVolume());
    System.out.println("Volume of Cube2 is : " + cubeObj2.getVolume());
  }
}

static

static modifikator označava da je atribut ili metoda zajednička svim instancama klase i da postoji iako nije kreirana nijedna instanca klase. Statičkim atributima i metodama se može pristupati kao i nestatičkim a može i koristeći ime klase. Na primer, Math.sqrt(4) gde je sqrt statička metoda Math klase koja prima jedan doulbe kao argument i vraća double.

Statički metodi ne dobijaju this! Za statičke metode je važno napomenuti da one ne mogu koristiti nestatičke metode iste klase direktno, niti pristupati nestatičkim varijablama.

Nestatičke metode mogu pristupati statičkim metodama i koristiti statičke atribute iste klase.

Statički atributi i metode se drugačije nazivaju članovi klase, dok se nestatički atributi i objekti drugačije nazivaju članovi objekta.

Getteri i setteri

Getteri i setteri su metode u objektno-orijentisanim jezicima poput Jave, koje služe za pristupanje (čitanje ili pisanje) privatnim atributima (članovima) objekta. Ovi metodi omogućavaju kontrolisani pristup i manipulaciju privatnim podacima klase.

Getter metode

Getteri su metode koje se koriste za čitanje (dobavljanje) vrednosti privatnih atributa objekta. Ime getter metode obično počinje sa “get” i vraća vrednost određenog atributa.

Primer getter metode u Javi:

public class Osoba {
    private String ime;

    public String getIme() {
        return ime;
    }
}

Ova getter metoda getIme() omogućava čitanje vrijednosti privatnog atributa ime.

Setter metode

Setteri su metode koje se koriste za postavljanje (postavljanje ili ažuriranje) vrednosti privatnih atributa objekta. Ime setter metode obično počinje sa “set” i postavlja novu vrijednost određenog atributa.

Primer setter metode u Javi:

public class Osoba {
    private String ime;

    public void setIme(String novoIme) {
        ime = novoIme;
    }
}

Ova setter metoda setIme() postavlja novu vrijednost privatnog atributa ime na osnovu proslijeđenog parametra novoIme.

Zašto koristiti gettere i settere?

Korišćenje gettera i settera omogućava bolju kontrolu i zaštitu privatnih atributa klase, te olakšava održavanje i razumevanje koda.