Statično in objektno

Statično in objektno

Avtor: Matija Lokar

Razred Datum

  • public class Datum {
      private int dan;
      private int mesec;
      private int leto;

    public override string ToString() {
      // datum v obliki dan.mesec.leto
      // mesec z besedo
      string datu = dan + "." +
         mesecZbesedo[mesec] + "." +
         leto + ".";
      return datu;
    }
  • Tabela mesecZbesedo
  • Ni lastnost posameznega datuma
  • Je skupna za vse objekte razreda Datum

Statične komponente

  • private static string[] mesecZbesedo =
       {"januar", "februar", "marec", ...}
  • static

    • Obstajajo neodvisno od obstoja objekta tega razreda
    • Le en primerek za cel razred!
  • Dostop private ali public (kot pri objektih)
  • Kako se skličemo nanje

    • Razred.ImeStaticneSpremenljivke
  • Ne potrebujejo new zato "da so".
  • Math.PI

Razred Datum

public class Datum {
     private int dan;
     private int mesec;
     private int leto;
     private string[] mesecZbesedo = {"", "januar", "februar", ...}

     public override string ToString() {
        // datum v obliki dan.mesec.leto
        // mesec z besedo
        string datu = dan + "." +
           Datum.mesecZbesedo[mesec] + "." + leto + ".";
        return datu;
    }
    ...
}

Statične spremenljivke

public class Foo {
    public static int x = 12;
    public int y;

    public Foo(int z) {
       this.y = z;
    }
}

  • x: statična komponenta, y: objektna (nestatična) komponenta
  • Statične komponente: vsebovane v razredu, objektne komponente: v objektih.
  • Vsak objekt vsebuje svojo kopijo objektnih komponent, vsaka statična komponenta pa vedno obstaja v eni sami kopiji.
    Foo t1 = new Foo(42);
    Foo t2 = new Foo(30);
  • Dva objekta - dve kopiji komponente y, po eno v vsakem objektu. Ker je komponenta x statična, vedno obstaja v eni sami kopiji, tudi če nimamo nobenih objektov razreda Foo:
(5.png)

Uporaba statičnih spremenljivk

  • Različne konstante
  • Enolična identifikacija

    • Objekt naj ima svojo serijsko številko
    • Denimo, da so te številke zaporedne
    • Vedeti, katera je bila dodeljena zadnja
    • Zadnja dodeljena številka: ni lastnost objekta, ampak cele skupine objektov
  • Vedno, ko je določen podatek skupen za vse objekte tega razreda
  • Kako vemo, ali naj bo komponenta statična ali objektna?

    • Statične komponente so tiste, ki so skupne za celoten razred – niso posebna lastnost enega (ali nekaj) primerkov objektov tega razreda.

Statične komponente - dostop

  • public ali private (odvisno od željenega načina dostopa)
  • public praviloma le, če gre za konstante

    • Pozor! Pri const ne napišemo static , a so vseeno statične (razredne)
    • Ne moremo imeti objektnih konstant (nima smisla)
    • zaradi const ni težav s pravilnostjo podatkov
    • konstante imajo način dostopa private , če jih želimo "skriti" pred uporabniki

Zajec

  • Radi bi vedeli, koliko zajcev imamo
  • Števec ustvarjenih objektov

    • NI lastnost posameznega zajca
    • SKUPNA lastnost
    • private static int kolikoZajcev = 0;

      • Na začetku 0
    • Spreminjamo takrat, ko ustvarimo novega zajca

      • new
      • V konstruktorju!
  • Serijska številka naj bo zagotovo enolična

    • Določimo jo le enkrat – ob rojstvu (konstruktor)
    • ZAJEC_n (če je to n-ti zajec)

Zajec

(9.png)

Štetje objektov in konstante

  • Zgled:

    • Štetje ustvarjenih objektov
    • V konstruktorjih povečujemo števec
    • Uporaba konstant
    • Meje pravilnosti podatkov so konstantne
(10.png)

Štetje objektov in konstante

(11a.png) (11b.png)

Zgled

(12.png) (12a.png)

Statične metode

  • Objekt:

    • Objektne komponente
    • Objektne metode
  • Skupno vse objektom – na nivoju razreda

    • statične metode
    • statične komponente
  • Statične metode se v neobjektnih programskih jezikih imenujejo "funkcije" ali "procedure", statične komponente pa se imenujejo "globalne spremenljivke".

Statične/objektne metode

  • Statično metodo Bla() v razredu Foo lahko vedno izvedemo z ukazom Foo.Bla() . Znotraj statične metode objekt this ni definiran, ker se statična metode ne kliče na objektu.
  • Objektno metodo Hej() v razredu Foo lahko izvedemo, če imamo neki objekt x razreda Foo , z ukazom x.Hej() . Znotraj metode Hej() označuje this objekt, na katerem je metoda poklicana.

Zgled

public class Foo {
    public static int x = 12;
    public int y;

    public Foo(int z) {
       this.y = z;
    }

    public static int F(int a) {     return x + a;   }
    // ali  return Foo.x + a;

    public int G(int a) {     return this.y + Foo.x + a;   }
    // ali y + Foo.x + a ALI y + x + a ALI ...
}

Zgled

  • Statična metoda F ima dostop do (statične) komponente x . Dostopa do komponente y nima, saj znotraj statične metode ne moremo pisati this.y .
  • Objektna metoda G ima dostop do komponente this.y , kjer je this objekt, na katerem je metoda g klicana. Prav tako ima dostop do (statične) komponente x .


int p = Foo.F(7);     // p == 12 + 7 == 19
Foo.x = -3;
int q = Foo.F(5);     // q == -3 + 5 == 2
Foo t = new Foo(100);
Foo s = new Foo(200);
int r = t.G(50);      // r == 100 + (-3) + 50 == 147

Statične metode

  • Kadar za izvajanje ne potrebujemo objekta tega razreda
  • Klic ImeRazreda.ImeMetode
  • Praviloma ne spreminjajo stanja nekega objekta
  • Vsi podatki podani preko parametrov metode
  • Main
  • Razred Math

Razred Datum

public class Datum {  private int dan;  private int mesec;  private int leto;
      private static string[] sloMesec = {"", "januar", ...};
      private static string[] engMonth = {"", "January", ...};
      private static string[] mesecZBesedo
      private static bool jezik = true; // jezik vseh datumov true – slo
                                        // false angl   public static void SpremeniJezik() {
          if (jezik) {
             mesecZBesedo = engMonth; // pokaže na isto tabelo
          } else {
             mesecZBesedo = sloMonth; // pokaže na isto tabelo
          }
          jezik = !jezik;
      }
    public override string ToString() {     // datum v obliki dan.mesec.leto     // mesec z besedo     string datu = dan + "." + mesecZbesedo[mesec] + "." + leto + ".";     return datu; }
    ...
}

Privatne metode

  • Tudi metode so lahko privatne

    • objektne, statične
  • private void MetodaA() {...};
  • private static int MetodaB{...};
  • Kadar metodo potrebujemo interno – uporabnikom ni potrebna!

Privatne statične metode

private static bool Kontrola(int x)
 { /* pomozna metoda, zato private, ni odvisna od objektov, zato static */
   // preverimo, ce velja MIN_DOL_STR <= x <= MAX_DOL_STR
       return ((Kvader.MIN_DOL_STR <= x) && (x <= Kvader.MAX_DOL_STR));
 }
------------------------------------------------------------------------------------
public Kvader(int s)
{
   // kocka s stranico s. èe podatek ni v redu - kocka z robom 1
   if (!((MIN_DOL_STR <= s) && (s <= MAX_DOL_STR))) s = 1; // ce podatek ni v mejah,
   ...
bolje
public Kvader(int s)
{
   // kocka s stranico s. èe podatek ni v redu - kocka z robom 1
   if (!Kontrola(s)) s = 1; // ce podatek ni v mejah,
   ...
še bolje
public Kvader(int s)
{
   // kocka s stranico s. èe podatek ni v redu - kocka z robom 1
   if (!Kvader.Kontrola(s)) s = 1; // ce podatek ni v mejah,
   ...

0%
0%