Objekti, razredi, ... II

Objekti, razredi, ... II

Avtor: Matija Lokar

Zgled – člani športnega kluba

  • Denimo, da bi radi napisali program, ki vodi evidenco o članih športnega kluba. Podatki o članu obsegajo ime, priimek, letnico vpisa v klub in vpisno številke (seveda je to poenostavljen primer). Torej objekt, ki predstavlja člana kluba, vsebuje štiri podatke:

public class Clan {
    public string ime;
    public string priimek;
    public int letoVpisa;
    public string vpisnaStevilka;
}

Klub - uporaba


using MojaKnjiznica;
public class TestKlub {
  public static void Main(string[] args) {

    Clan a = new Clan();
    a.ime = "Janez";
    a.priimek = "Starina";
    a.letoVpisa = 2000;
    a.vpisnaStevilka = "2304";

    Clan b = new Clan();
    b.ime = "Mojca";
    b.priimek = "Mavko";
    b.letoVpisa = 2001;
    b.vpisnaStevilka = "4377";
(2.png)


    Clan c = b;
    c.ime = "Andreja";

    Console.WriteLine("Clan a:\n" + a.ime + " " + a.priimek +
                      " " + a.letoVpisa + " (" + a.vpisnaStevilka + ")\n");

    Console.WriteLine("Clan b:\n" + b.ime + " " + b.priimek +
                      " " + b.letoVpisa + " (" + b.vpisnaStevilka + ")\n");
     Console.WriteLine("Clan c:\n" + c.ime + " " + c.priimek +
                      " " + c.letoVpisa + " (" + c.vpisnaStevilka + ")\n");
    Console.ReadLine();
  }
}

Zakaj


public class TestKlub {
  public static void Main(string[] args) {

    Clan a;
    a = new Clan();
            a.ime = "Janez";
    a.priimek = "Starina";
    a.letoVpisa = 2000;
    a.vpisnaStevilka = "2304";

    Clan b = new Clan();
    b.ime = "Mojca";
    b.priimek = "Mavko";
    b.letoVpisa = 2001;
    b.vpisnaStevilka = "4377";
(3.jpg)


    Clan c;
            c = b;
    c.ime = "Andreja";

    Console.WriteLine("Clan a:\n" + a.ime + " " + a.priimek +
                      " " + a.letoVpisa + " (" + a.vpisnaStevilka + ")\n");

    Console.WriteLine("Clan b:\n" + b.ime + " " + b.priimek +
                      " " + b.letoVpisa + " (" + b.vpisnaStevilka + ")\n");
    Console.WriteLine("Clan c:\n" + c.ime + " " + c.priimek +
                      " " + c.letoVpisa + " (" + c.vpisnaStevilka + ")\n");
    Console.ReadLine();
  }

Zgled – športni klub, nadaljevanje

  • Spremenimo sedaj naš razred Clan tako, da bomo uporabili konstruktor


public class Clan {
    public string ime;
    public string priimek;
    public int letoVpisa;
    public string vpisnaStevilka;

    public Clan(string i, string p, int l, string v) {
        this.ime = i;
        this.priimek = p;
        this.letoVpisa = l;
        this.vpisnaStevilka = v;
    }
}

Šprtni klub - test

  • Bo naš testni program OK?
  • Poženimo
  • Napake!

    • Kako, rekli smo, da spreminjanje razreda ne vpliva na uporabniške programe
    • Spremenili smo način uporabe
    • V testnem programu: Clan()

      • Tega sedaj ni

        • C# ga naredi sam le, če nismo napisali nobenega konstruktorja

Popravljeni zgled


public class Clan {
    public string ime;
    public string priimek;
    public int letoVpisa;
    public string vpisnaStevilka;

    public Clan() {
    this.ime = "Ne vem";
    this.priimek = "Ne vem";
    this.letoVpisa = 0;
    this.vpisnaStevilka = "Ne vem";
    }

    public Clan(string i, string p, int l, string v) {
    this.ime = i;
    this.priimek = p;
    this.letoVpisa = l;
    this.vpisnaStevilka = v;
    }
}

Poskus testa

  • Ni težav!
  • Zakaj ves ta napor, če pa je na koncu le isto ...
  • Preglednost!

    • In priprava za naprej

Primerjava: brez / s konstruktiorjem


public class TestKlub {
  public static void Main(string[] args) {
     Clan a = new Clan();
    a.ime = "Janez";
    a.priimek = "Starina";
    a.letoVpisa = 2000;
    a.vpisnaStevilka = "2304";

    Clan b = new Clan();
    b.ime = "Mojca";
    b.priimek = "Mavko";
    b.letoVpisa = 2001;
    b.vpisnaStevilka = "4377";

    Clan c = b;
    c.ime = "Andreja";
...

public class TestClan{
    public static void Main(string[] args) {
        Clan a = new Clan("Janez",
                "Starina", 2000, "2304");
    Clan b = new Clan("Mojca",
                "Mavko", 2001, "4377");
          Clan c = b;
    c.ime = "Andreja";
    ...

Objektne metode

  • V definicijo razreda običajno spadajo tudi metode
  • Klic objektnih metod:

    • imeObjekta.imeMetode(parametri)
    • System.Console.WriteLine("To naj se izpiše");
    • besedilo.Equals(primerjava)
  • Metoda v razredu Clan public string Inicialke() {
       return this.ime[0] + "." + this.priimek[0] + ".";
    }

Uporaba metode

using MojiRazredi; // knjižnica z razredom Clan
public class TestClan{
    public static void Main(string[] args) {
       Clan a = new Clan("Janez", "Starina", 2000, "2304");
       String inicialkeClanaA = a.Inicialke();
       Console.Write("Clan a:\n" + a.ime + " " + a.priimek +
               " " + a.letoVpisa + " (" + a.vpisnaStevilka + ") ");
       Console.WriteLine("ima inicialke: " + inicialkeClanaA);
    }
}

  • a.Inicialke() = klic metode

Sprememba metode

public class Clan {
    public string ime;
    public string priimek;
    public int letoVpisa;
    public string vpisnaStevilka;

    public Clan() {
   ime = "Ne vem";
   priimek = "Ne vem";
   letoVpisa = 0;
   vpisnaStevilka = "Ne vem";
    }
    public Clan(string i, string p, int l, string v) : this() {
      ime = i;
   priimek = p;
   letoVpisa = l;
   vpisnaStevilka = v;
    }
    public string Inicialke() {
   return this.ime[0] + " " + this.priimek[0];
    }
}

  • Spremembe v TestClan niso potrebne!

Metoda, ki vrača objekt iz Razreda

  • Vemo, da z

    • a = b;
  • kjer sta a in b obe spremenljivki tipa Clan, v a ne shranimo kopije objekta b, ampak sedaj a in b označujeta isti objekt.
  • Metoda, ki naredi kopijo objekta.

    • a = b.Kopija();

      • V a je nov objekt, ki pa ima iste podatke kot b.

Kopija

public Clan Kopija() {
    Clan nov = new Clan();
    nov.ime = this.ime;
    nov.priimek = this.priimek;
    nov.letoVpisa = this.letoVpisa;
    nov.vpisnaStevilka =
         this.vpisnaStevilka;
    return nov;
}

Še metoda za izpis

public void Izpis() {
  Console.WriteLine("Clan:\n" + this.ime + " " +
     this.priimek + " " + this.letoVpisa +
     " (" + this.vpisnaStevilka + ")\n");
}

ali pa še


public string Opis() {
  return this.ime + " " + this.priimek + " " +
         this.letoVpisa +
         " (" + this.vpisnaStevilka + ");
}

Uporaba


public class TestKlub {
  public static void Main(string[] args) {

    Clan a = new Clan("Janez", "Starina", 2000, "2304");
    Clan b = new Clan("Mojca", "Mavko", 2001, "4377");
    Clan c = b;
    c.ime = "Andreja";
    Clan d = b.Kopija();
    d.ime = "Tadeja";

    Console.WriteLine("Clan a"); a.Izpis();
    Console.WriteLine("Clan b:\n" + b.Opis());
    Console.WriteLine("Clan c:\n" + c);
    Console.WriteLine("Clan d"); d.Izpis();
    Console.ReadLine();
  }
}

Razred Datum

  • Denimo, da v naših programih pogosto delamo z datumi.
  • Zato bomo sestavili ustrezni razred
  • Načrt razreda:

    • Podatki

      • dan (število)
      • mesec (izbira: število ali pa niz)
      • Leto (število)
    • Metode

      • Konstruktorji
      • Izpiši
      • Povečaj za 1 dan
      • Je datum smiselen
      • Je leto prestopno
      • Nov datum za toliko in toliko dni pred/za danim datumom
      • Dan v tednu
      • ...

Datum – podatki in konstruktor


public class Datum {
   public int dan;
   public string mesec;
   public int leto;

   public Datum() {
      dan = 1;
      mesec = "januar"
      leto = 2000;
   } // privzeti datum je torej 1.1.2000

Dodatni konstruktorji


public Datum(int leto) : this() {
  this.leto = leto; // this je nujen
} // datum je torej 1.1.leto

public Datum(int d, string m, int l) : this(l)
{ // leto smo že nastavili
  this.mesec = m; // this ni nujen
  this.dan = d;
} // datum je torej d.m.l (na primer 12.3.2006 ali
  // 12. marec 2006)

Prestopno

  • Zanima nas, ali je leto prestopno

public bool JePrestopno() {
   int leto = this.leto;
   if (leto % 4 != 0) return false;
   if (leto % 400 == 0) return true;
   if (leto % 100 == 0) return false;
   return true;
}

Dodaj en dan


public void PovecajZaEnDan() {
   dan = dan + 1;
   if (dan < 29) return;
   if (dan == 29 && mesec != "februar") return;
   if (dan == 29 && mesec == "februar" && this.JePrestopno()) return;
// lahko nehamo, mesec in leto sta ok
   string[] meseciPo30 = {"april","junij","september", "november"};

(20.jpg)

Uporaba razreda

  • Ugotovi, če je letošnje leto prestopno!  using MojiRazredi;

    public class JeLetosPrestopnoLeto {
       Datum danes = new Datum(5, 3, 2009);
       if (danes.jePrestopno()) {
         Console.WriteLine("Je prestopno leto");
       } else {
         Console.WriteLine("Ni prestopno leto");
       }
    }

Sprememba razreda

  • Imamo if (enClan.letoVpisa > drugClan.letoVpisa) { …
  • Spremenimo razred Clan, tako, da vodimo datum vpisa
(22.jpg)

Sprememba razreda

(23.jpg)

Sprememba razreda


public string Opis() {
    return this.ime + " " + this.priimek + " " +
      this.datumVpisa.OpisDat() + " (" + this.vpisnaStevilka + ");
  }

   public string ToString() {
      return this.Opis();
    }

    public bool SpremeniLetoVpisa(int l) {
      if ((2000 <= leto) && (leto <= 2020)) {
        this.datumVpisa.leto = l;
        return true; //leto je smiselno, popravimo stanje objekta in vrnemo true
       }
       return false; // leto ni smsielno, ne spremnimo inč in vrnemo false
    }
}

Sprememba razreda

(25.jpg)

Sprememba razreda

(26.jpg)

Način programiranja

  • Seveda zaradi spremembe
    if (enClan.letoVpisa >
      drugClan.letoVpisa) { …
  • ne deluje več!
  • Kako popraviti?

Že v prvotnem razredu


public class Clan {
    public string ime;
    public string priimek;
    public int letoVpisa;
    public string vpisnaStevilka;

    public bool SpremeniLetoVpisa(int leto) {
      if ((2000 <= leto) && (leto <= 2020)) {
        this.letoVpisa = leto;
        return true;
       }
       return false; // leto ni smiselno, ne spremnimo nič in vrnemo false
    }
    public int VrniLetoVpisa() {
      return this.letoVpisa;
    }
}


if (enClan.VrniLetoVpisa() >
    drugClan.VrniLetoVpisa()) { …

Ob spremembi razreda Clan

(29.jpg)
0%
0%