290 likes | 445 Views
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:
E N D
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 intletoVpisa; 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"; 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 a ime: Janez priimek: Starina b ime: Mojca priimek: Mavko ANDREJA c 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"; 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 intletoVpisa; 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 nobenegakonstruktorja
Popravljeni zgled public class Clan { public string ime; public string priimek; public intletoVpisa; 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 Klic 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("imainicialke: " + inicialkeClanaA); } }
Sprememba metode Spremembe v TestClan niso potrebne! public class Clan { public string ime; public string priimek; public intletoVpisa; 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]; } }
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 Smiselno je, da je tudi mesec int! Narobe, mesec je string Sintaktično prav, a semantično narobe – mesec je niz! Ponovno za "risalno desko" – razred spremnimo tako, da je mesec int. Dokončaj za vajo! 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"}; if (dan == 31) { if (meseciPo30.IndexOf(mesec) > 0){ mesec = mesec + 1; if (mesec == 13) { mesec = 1; leto++; } return; } // če je 32 dni, je zagotovo
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 Clan y = new Clan(); y Ime: "Ne vem" Priimek: "Ne vem" datumVpisa vpisnaStevilka: "Ne vem" dan: 1 mesec: 1 leto: 2000 Imamo if (enClan.letoVpisa> drugClan.letoVpisa) { … Spremenimo razred Clan, tako, da vodimo datum vpisa public class Clan { public string ime; public string priimek; public Datum datumVpisa; public string vpisnaStevilka; public Clan() { ime = "Ne vem"; priimek = "Ne vem"; datumVpisa= new Datum(); vpisnaStevilka= "Ne vem"; }
Sprememba razreda Metoda Kopija iz razreda Datum!!!! Nima zveze z metodo Kopija iz razreda Clan public Clan(string i, string p, Datum d, string v) : this() { ime = i; priimek = p; datumVpisa= d; vpisnaStevilka= v; } public string Inicialke() { return this.ime[0] + "." + this.priimek[0] + "."; } public Clan Kopija() { Clan nov = new Clan(); nov.ime = this.ime; nov.priimek = this.priimek; nov.datumVpisa= this.datumVpisa.Kopija(); nov.vpisnaStevilka= this.vpisnaStevilka; return nov; } public void Izpis() { Console.WriteLine("Clan:\n" + this.ime + " " + this.priimek+ " " + this.datumVpisa.OpisDat() + " (" + this.vpisnaStevilka+ ")\n"); }
Sprememba razreda public string Opis() { return this.ime + " " + this.priimek + " " + this.datumVpisa.OpisDat() + " (" + this.vpisnaStevilka + "); } public string ToString() { return this.Opis(); } public boolSpremeniLetoVpisa(int l) { if ((2000 <= leto) && (leto <= 2020)) { this.datumVpisa.leto = l; return true; //leto je smiselno, popravimostanjeobjekta in vrnemo true } return false; // letonismsielno, ne spremnimoinč in vrnemo false } }
Sprememba razreda public Clan(string i, string p, Datum d, string v) : this() { ime = i; priimek = p; datumVpisa= d; vpisnaStevilka= v; } public string Inicialke() { return this.ime[0] + "." + this.priimek[0] + "."; } public Clan Kopija() { Clan nov = new Clan(); nov.ime = this.ime; nov.priimek = this.priimek; nov.datumVpisa= this.datumVpisa.Kopija(); nov.vpisnaStevilkaevilka= this.vpisnaStevilka; return nov; }
Sprememba razreda public void Izpis() { Console.WriteLine("Clan:\n" + this.ime + " " + this.priimek + " " + this.datumVpisa.OpisDat() + " (" + this.vpisnaStevilka+ ")\n"); } public string Opis() { return this.ime + " " + this.priimek + " " + this.datumVpisa.OpisDat() + " (" + this.vpisnaStevilka+ "); } public boolSpremeniLetoVpisa(int l) { if ((2000 <= leto) && (leto <= 2020)) { this.datumVpisa.leto= l; return true; //leto je smiselno, popravimostanjeobjekta in vrnemo true } return false; // letonismiselno, ne spremenimo nič in vrnemo false } }
Način programiranja Seveda zaradi spremembe if (enClan.letoVpisa> drugClan.letoVpisa) { … ne deluje več! Kako popraviti?
Že v prvotnem razredu if (enClan.VrniLetoVpisa() > drugClan.VrniLetoVpisa()) { … public class Clan { public string ime; public string priimek; public intletoVpisa; public string vpisnaStevilka; public boolSpremeniLetoVpisa(intleto) { if ((2000 <= leto) && (leto <= 2020)) { this.letoVpisa= leto; return true; } return false; // letonismiselno, ne spremnimonič in vrnemo false } public intVrniLetoVpisa() { return this.letoVpisa; } }
Ob spremembi razreda Clan Enak podpis, enak tip rezultata – spremembe v uporabniških programih niso potrebne Le metodo public intVrniLetoVpisa() { return this.letoVpisa; } zamenjamo z public intVrniLetoVpisa() { return this.datumVpisa.leto; }