Win
Klasa (class)
Klasa (Class) je osnova Objektno Orijentiranog Programiranje. Ona predstavlja objekt. Objekt definiramo kao neku cjelinu (nešto što ima granice), bilo realnu ili virtualnu.
Klasa se sastoji od konstruktora i članova klase. Za ilustraciju je pogodna jednostavna klasa ReportLabel. Radi predodžbe: Klasa Report (štampani izvještaj) se sastoji od više klasa Band (djelovi izvještaja), koji sadrže kolekcije klasa ReportLabel (pojedinačni tekst na izvještaju).
public class ReportLabel
{
// polja sa prperty pristupom
private string text = "";
private bool alignToBand = false;
private Font font = null;
// članovi sa direktnim pristupom
public int Left = 0;
public int Top = 0;
public int Width = 100;
public int Height = 25;
public int Alignment = 0; // 0 Lijevo 1 sredina 2 desno
public string ColumnName = "";
public string Sum = ""; // sumira polje ColumnName
public bool DrawFrame = false;
public Color BackColor = Color.Empty;
public int View = 0;
}
Konstruktor je funkcija koja gradi instancu klase. Instanca je u stvarnosti memorijski prostor za smještaj podataka o toj klasi za tu potrebu. Osnovni konstruktor klase nije naveden, kao u ovom slučaju, konstruktor je implicitan. Osnovni konstruktor ima isto ime kao i klasa i ne sadrži parametre. Konstruktor bez parametara radi instancu identičnu izvornoj klasi. Potrebne promjene se rade u procesu rada sa instancom.
ReportLabel()
{
}
Klasa može imati više konstruktora i obično sa slažu od jednostavnijeg prema složenijem. Ovakve konstruktore koristimo da bi skratili kodiranje. Na primjer svaka instanca iz primjera treba imati svojstvo 'Text', pa je najzgodnije definirati kroz konstruktor, kao u slijedećem primjeru.
public ReportLabel(string caption)
{
this.Text = caption;
}
// drugi konstruktor
public ReportLabel(string caption, int alignment)
{
this.Text = caption;
this.Alignment = alignment;
}
Prethodni konstruktori nam rade instancu u kojoj je (prije upotrebe) već definiran član 'private string text' i ' public int Alignment'
Članovi klase mogu biti svojstva, metode i događaji (event). Obični član klase kao
public int Left = 0;
i slični, se ne prakticira kod kontrola koje se uređuju Windows Form Designerom, jer su u tom slučaju nedostupne za njega. Svojstvo (Property) je isti takav član kojem se pristupa preko (funkcije) naziv svojstva, a vrijednost (uvijek value) se čuva u privatnom članu klase ka pr.
private string text = ""; // privatni član kojeg koristi javno svojstvo 'Text'
……
public string Text
{
get {return text;}
set {text = value;}
} //----------------------------------------------------------------------
Korištenjem property-a postižemo da nam objekti budu pametni. U čemu je riječ: Mnogi članovi unutar klase su međuzavisni, pa promjenom jednoga klasa mora sama podesiti drugi koji je ovisan od promjenjenog. Tu zakonitost i međuovisnost ugradimo set{} propertija, pa na primjer u ReportLabel član Height ne može biti manji od visine teksta za zadani font. Set{} funkcija izračunava visinu texsta i ako je zadana virijednost Height manja od te vrijednosti, vrijednost postavlja na veću. U primjeru nasljeđivanje klasa 'columns.set{}' kreira kolekcije ReportBand.Labels sa sve trake koje prezentiraju kolone izvještaja.
Instanca klase
Klasa se gotovo nikad ne koristi u 'izvornom' obliku, nego se koristimo instancom te klase. Program smješta o memoriju klasu, a kada kreiramo instancu mi osiguramo prostor za promjenjive koje se odnose na instancu (kopiju) te klase sa kojom radimo. Instancu klase si je najlakše predočit kao kopiju slike. Neka je klasa neka 'slika', preko nje stavimo prozirni papir i na njemu radimo izmjene u odnosu na izvornu sliku, tako da ono što ostaje isto ne diramo. Taj prozirni papir je instanca klase 'slika'
Klasa ima (može imat) više instanci istovremeno, koje su međusobno neovisne. Baz instanciranja se koristi samo tzv. Singeltone klasa koja sadrži samo konstante označene kao static, primjer je klasa User.
class User
{
public static string ImeProg = "DEMO d.o.o.";
public static string DatumIzrade = "August, 1998";
public static string RadniDir = "D:\\Program\\Data";
………
……….
public static string Grad = "POTPIĆAN";
public static string Tel = "052 867-511";
}
Takva klasa ne treba instancu jer su članovi statični i uvijek se pozivaju na istom mjestu, pa se koristi kao 'skladište' globalnih promjenjivih programa. Static označava da je neka promjenjiva konstantna u smislu pozicije u memoriji računala, i sve instance klasa koje se pozivaju na tu promjenjivu čitaju istu vrijednost.
Instancu si možemo predočit kao neku vrstu kopije koja se da dotjerat prema trenutnoj potrebi. U suštini kreiranjem instance mi kreiramo memorijski prostor za promjenjive koje se odnose na klasu, a koje je modificiraju prema potrebi instance.
Instanca klase bi mogla izgledati ovako:
ReportLabel lb2 = new ReportLabel("U K U P N O :");
lb2.Top = 1;
PageFooter.Labels.Add(lb2);
U prvom redu smo koristili konstruktor koji odmah definira Text property. U drugom redu smo definirali član 'Top instance 'lb2', i na kraju smo instancu dodali u neku kolekciju što sada nije bitno.
Sa new smo rezervirali memorijski prostor instance lb2 u kojem se trenutno nalaze promjenjene vrijednosti članova 'Text' i 'Top'. Po konvenciji kodiranja instanca bi trebala nosit naziv 'reportLabel' isto kao i klasa samo počinje malim slovom. Ovdje se od toga odstupilo radi cijele hrpe instanci unutar nekog izvještaja, pa onda čitljivost treba osigurat na drugi (ovakav) način.
Nasljeđivanje klasa
Nasljeđivanje je jedno od najmoćnijih oružja OOP jezika. Pod nasljeđivanjem se podrazumijeva kada kreiramo neku klasu kao nadogradnju na već postojeću. To bi si mogli predstavit kao klasa 'šasija' vozila, sada na šasiju ugradimo sanduk za teret kao klasa 'kamion', na drugu šasiju ugradimo putničku kabinu kao klasa 'kombi'. U ovom primjeru i šasija i obje (različito) nadogradnje su cjeline same za sebe ili klase, obje nadogradnje nasljeđuju svojstva šasije (osnovne klase). Primjer za to možemo navest više vrsta izvještaja koji su svaki za sebe cjelina, a nadograđuju se
// Jednostavni (jedan list) izvještaj sa samo headerom i footerom,
public class BaseReport
{
public PrintDocument printDoc;
protected PrintPreviewDialog stdPreview = new PrintPreviewDialog();
public ReportBand PageHeader; // public jer se dorađuje preme potrebi
public ReportBand PageFooter;
public BaseReport() {
this.printDoc = new PrintDocument();
this.printDoc.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.printDoc_PrintPage);
this.stdPreview.Document = printDoc;
this.PageHeader = new ReportBand();
this.PageFooter = new ReportBand();
} //----------------------------------------------------------------------
virtual protected void printDoc_PrintPage(object Sender, PrintPageEventArgs ev) {
………………..
…………………
DrawBand(PageHeader, ev);
DrawBand(PageFooter, ev);
} //---------------------------------------------------------------------- }
Naslijeđuje ga klasa
// izvještaj nadograđen na BaseReport, sa ColumnHeader, DetailBand, SumaryBand.
public class StandardReport:BaseReport
{
protected string[] columns;
public ReportBand ColumnHeader = new ReportBand();
protected ReportBand IndexBand = new ReportBand();
protected ReportBand DetailBand = new ReportBand();
public ReportBand SumaryBand = new ReportBand();
public StandardReport() {
this.printDialog = true;
this.IndexBand.Height = 15;
this.IndexBand.Font = new Font("Times New Roman", 8, FontStyle.Regular);
} //----------------------------------------------------------------------
override protected void printDoc_PrintPage(object Sender, PrintPageEventArgs ev) {
……………………….
………………………..
DrawBand(PageHeader, ev);
DrawBand(ColumnHeader, ev);
……………………..
for(int i = rowsProcessed; i <= rowsCount; i ++) {
…………….
DrawBand(DetailBand, ev);
……………
}
} //---------------------------------------------------------------------- }
Primjeri su maksimalno reducirani, jer se nastojalo prikazat princip djelovanja, a ne rješenje.
Ako pogledamo primjer vidimo da smo napisali potpuno novi, složeniji izvještaj bez ponavljanja onoga što već imamo, samo dodajemo nove dijelove ili prepravljamo postojeće.
Ako želimo pristup članovima klase u naslijeđenoj klasi onda oni moraju biti protected. Public članovi su dostupni i izvan klase pa su samim time i iz nasljedne klase. Neke metode ili eventi bi možda željeli da u novonastaloj klasi izgledaju drukčije, pa ih možete prekrit sa novom metodom ili eventom. Ključna riječ je virtual i override kao u primjeru.
Nasljeđivanje je vraški praktična stvar kod pisanja programa jer stvara maksimalno konvergentni kod, koji je jako jednostavan za održavanje.
