You are on page 1of 46

OOP vebe eljko Jovanovi

VEBE 01 OBNAVLJANJE FUNKCIJA I STRUKTURA


1. Napisati program koji rauna hipotenuzu pravouglog trougla pomou funkcije.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
float a, b;
Console.WriteLine("Uneti stranice pravouglog trugla ");
a = Convert.ToInt32(Console.ReadLine());
b = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Hipotenuza je: " + hipotenuza(a, b));
Console.ReadLine();
}
static double hipotenuza(float a, float b)
{
double c;
c = Math.Sqrt(Math.Pow(a, 2) + Math.Pow(b, 2));
return c;
}
}

2. Napisati program u kome se definie funkcija prost koja ispituje da li je broj prost i funkcija
main() koja njenim korienjem tampa sve proste brojeve od 3 do datog prirodnog broja n.
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
int i, n;
Console.WriteLine("Uneti broj n ");
n = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Prosti brojevi od 3 do " + n + " su ");
for (i = 3; i <= n; i++)
if (prost(i))
Console.WriteLine(i);

Console.ReadLine();
}
static bool prost(int n)
{
int i;
for (i = 2; i <= Math.Sqrt(n); i++)
if (n % i == 0)
return false;
return true;
}

OOP vebe eljko Jovanovi


Strukture
Strukture su pretee klasa. Na sledeem primeru emo pokazati kako se dolo do ideje o kreiranju
objektno orjentisanih jezika. Primer sa strukturom demonstrira kako neke funkcije (metode) rade sa
strukturom sto e se u objektnom nainu programiranja promeniti u metode neke klase kao njene
mogunosti.
Ulazno/izlazna sintaksa je razliita u skoro svim jezicima :
Konkretno da bi se ispisala ili unela vrednost celobrojne promenljive koriste se:
C
printf(%d, i);
scanf(%d, &i);

C++
cout<<i;
cin>>i;

C#
Console.WriteLine(i);
i=Console.ReadLine();

3. Napisati program za formiranje strukture student sa karakteristikama: Ime, Prezime, broj indeksa,
srednja ocena. Za uneti broj studenata n, sortirati studente prema srednjoj oceni i ispisati na ekranu.
namespace ConsoleApplication3
{
class Program
{
// sve atribute strukture postaviti public (objasnjenje na sledecem casu)
struct Student
{
public String ime;
public String prezime;
public int br_indeksa;
public double sred_ocena;
}
static void Main(string[] args)
{
int n, i;
Student[] STF = new Student[20];
String im, p;
int b;
double s;
Console.WriteLine("Unesite broj studenata: ");
n = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Unesite podatke o studentima:");
for (i = 0; i < n; i++)
{
Console.WriteLine("\nIme studenta: \n");
im = Console.ReadLine();
Console.WriteLine("Prezime studenta: \n");
p = Console.ReadLine();
Console.WriteLine("Broj indeksa: ");
b = Convert.ToInt32(Console.ReadLine()); ;
Console.WriteLine("Srednja ocena studenta: \n");
s = Convert.ToDouble(Console.ReadLine()); ;
STF[i] = setStudent(im, p, b, s);
}

OOP vebe eljko Jovanovi


sort(STF, n);

for (i = 0; i < n; i++)


{
getStudent(STF, i);
}
Console.ReadLine();

static Student setStudent(String im, String p, int b, double s)


{
Student pom;
pom.ime = im;
pom.prezime = p;
pom.br_indeksa = b;
pom.sred_ocena = s;
return pom;
}
static void getStudent(Student[] STF, int i)
{
Console.WriteLine("\nIme : " + STF[i].ime);
Console.WriteLine("Prezime : " + STF[i].prezime);
Console.WriteLine("Broj indeksa: " + STF[i].br_indeksa);
Console.WriteLine("Srednja ocena : " + STF[i].sred_ocena);
}

static void sort(Student[] STF, int n)


{
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
if (STF[i].sred_ocena < STF[j].sred_ocena)
{
Student tmp = STF[i];
STF[i] = STF[j];
STF[j] = tmp;
}
}

OOP vebe eljko Jovanovi

VEBE 02 VREDNOSNI I REFERENTNI PODACI I METODE

Tipovi podataka

Definiu:
o skup dozvoljenih vrednosti,
o operacije nad tipom i
o veliine dozvoljenih vrednosti
C# sadri niz ugraenih tipova koji se nazivaju prosti tipovi.
CTS (Common Type System) je sastavni deo CLR-a (Common Language Runtimenajvaniji deo .Net framework-a nadlean za aktiviranje objekata, izvravanje bezbednosnih
provera, smetanje i uklanjanje iz memorije.. ), koji definie pravila za deklarisanje,
korienje i upravljanje tipovima (podrava vrednosne i referentne tipove).
int, long: uvanje celih brojeva
float, double: brojevi sa decimalnim zarezom (double moe da prihvati broj sa preciznou
duplo veom od broja u promenljivoj tipa float)
decimal: za uvanje novanih vrednosti od 28 znaajnih cifara
char: za pojedinane znakove
string: niz znakova
bool: tano, netano

- C# ima 15 predefinisanih tipova od kojih su 13 vrednosni, a 2 su referentni tipovi (string i object).


- Od tipova podataka koje promenljiva treba da sadri zavisi da li e ona biti vrednosnog ili
referentnog tipa.
- Object je osnovna klasa koja predstavlja bilo koji tip, odnosno iz nje se izvode svi ostali tipovi.

OOP vebe eljko Jovanovi

Metode
[modifikator] Tip_povratne_vrednosti Naziv_metode([lista_parametara]) {telo_metode}

Metod je imenovani niz iskaza.


Metod je lan klase koji izvrava neku logiku
Svaki metod ima ime i telo.
Telo metoda sadri same iskaze koje treba izvriti kada se metod pozove.
o Ime metoda treba razumljivo da identifikuje sveukupnu svrhu metoda.
C# ne podrava globalne metode.
Uvek mora pripadati nekoj klasi ili zapisu.
Naredba return se moe koristiti da bi se izvravanje momentalno vratilo iz metode na
mesto poziva (moe se vratiti iskljuivo jedna vrednost).

Prenos parametara metoda:


Parametri metoda se mogu deklarisati i sa:
ref
out
params.
Kada se metodu prosledi arugment, parametar se inicijalizuje kao kopija argumenta. To znai da
nikakva izmena parametra ne moe da utie na sam argument. Primer:
{

static void Inkrement(int parametar)

parametar++;
}
static void Main()
{
int a = 5;
Inkrement(a);
Console.WriteLine(a);
}

U ovom sluaju vrednost parametra a pri ispisu je i dalje 5, bez obzira to je pozvana metoda za
inkrementiranje. Ovo vai i za argumente referencnog tipa (klase, nizove). U sluaju kada treba
napisati metod koji treba da izmeni argument, koristie se kljune rei ref i out.
Za prenos po referenci se koristi kljuna re ref. Ova kljuna re se koriste i u definiciji
metoda i na mestu poziva. Prenos parametara po referenci omoguava bone efekte metoda nad
njima ne pravi se kopija stvarnog argumenta ve se izmene vre nad njim. Izlazni parametri ne
moraju da budu inicijalizovani pre prosleivanja metodi. Ako se izlaznom parametru ne pridrui
vrednost u metodi, javlja se greka. Primer:
{

static void Inkrement(ref int parametar)

parametar++;
}
static void Main()
{
int a = 5;
Inkrement(ref a);
Console.WriteLine(a);
}

OOP vebe eljko Jovanovi


U ovom sluaju izlazna vrednost argumenta a je 6. Na isti nain je mogue je da se primeni
parametar ref i na string.
{

class Primer2Ref
static void Metod(ref string s)
{
s = "izmenjen tekst";
}
static void Main()
{
string str = "originalni tekst";
Metod(ref str);
Console.WriteLine(str);
}

Definisanje out parametra je slino definisanju ref parametra. Ako ispred parametra
upotrebimo kljunu re out, to znai da parametar postaje alijas argumenta (referentna promenljiva
je alternativno ime za drugu promenljivu). Kada argument prosledimo parametru out, mora i ispred
argumenta da se upotrebi kljuna re out. Razlika izmeu parametra ref i out je to metod ne mora
da dodeli vrednost ref parametru, ali out parametru mora da dodeli vrednost. Prethodni primer ne
moe proi prevoenje zato to u metodu Inkrement nije dodeljena vrednost za parametar.
class PrimerOut1
{
static void Inkrement(out int parametar)
{
parametar=5;//Inicijalizacija u metodi
parametar++;
}
static void Main()
{
int a ;
Inkrement(out a);
Console.WriteLine(a);
}
}

Rezultat je 6. Mogue je u metodi koristiti vie parametara kojima se prosleuje out.


class PrimerOut2
{
static void Method(out int i, out string s1, out string s2)
{
i = 20;
s1 = "Ja sam prvi string";
s2 = null;
}
static void Main()
{
int vrednost;
string string1, string2;
Method(out vrednost, out string1, out string2);
Console.WriteLine("vrednost=" + vrednost + " string1= "
+ string1 + " string2= " + string2);
// vrednost je 20
// string1 je "Ja sam prvi string"
// string2 je null;
}
}

Kljuna re params odreuje parametar metoda koji uzima promenljivi broj argumenata. Tako je
mogue proslediti listu argumenata razdvojenih zarezom u deklaraciji parametara ili niz argumenata

OOP vebe eljko Jovanovi


odreenog tipa. Takoe, je mogue da se ne prosledi ni jedan argument. U deklaraciji metoda
dozvoljen je samo jedna kljuna re params.
PRIMER: Napisati konzolnu aplikaciju za demonstriranje razliitih naina slanja argumenata
params parametru.
public class PrimerParams
{
public static void MetodParams(params int[] niz)
{
for (int i = 0; i < niz.Length; i++)
{
Console.Write(niz[i] + " ");
}
Console.WriteLine();
}
// Niz se deklarie kao tip object (referentni tip podatka)
//a to je niz bilo kojih tipova podataka
public static void MetodParams2(params object[] niz)
{
for (int i = 0; i < niz.Length; i++)
{
Console.Write(niz[i] + " ");
}
Console.WriteLine();
}
static void Main()
{
// Moe se proslediti niz elemenata odreenog tipa razdvojenih zarezom.
MetodParams(1, 2, 3, 4);
MetodParams2(1, 'a', "test");
// Parametar params moe prihvatiti nula ili vie argumenata.
// Naredni poziv metoda prikazuje samo prazan red.
MetodParams2();
// Niz arugmenata se moe prosleivati sve dok se tip niza poklapa
// sa tipom parametra metoda koji se poziva.
int[] mojIntNiz = { 5, 6, 7, 8, 9 };
MetodParams(mojIntNiz);
object[] mojNizObjekata = { 2, 'b', "test", "ponovo" };
MetodParams2(mojNizObjekata);
// Sledei poziv prouzrokuje pojavu greke zato to
// niz objekata ne moe biti konvertovan u celobrojni niz.
//MetodParams(mojNizObjekata);
// Sledei poziv ne prouzrokuje greku, ali ceo celobrojni niz
// postaje prvi element params niza.
MetodParams2(mojIntNiz);
}

OOP vebe eljko Jovanovi


ZADATAK. Napisati konzolnu aplikaciju u kojoj se korienjem samo jedno funkcije nalazi broj
elemenata niza koji su jednaki minimalnom elementu niza i srednja vrednost parnih elemenata u
nizu.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Nizovi
{
class Program
{
static void unos(int[] niz)
{
int i;
for (i = 0; i < niz.Length; i++)
niz[i] = Convert.ToInt32(Console.ReadLine());
}
static void izracunavanje(int[] niz, ref int broj, ref float sv)
{
//nalazenje minimalne vrednosti u nizu
int min = niz[0];
for (int i = 1; i < niz.Length; i++)
{
if (niz[i] < min)
min = niz[i];
}
//nalazenje koliko ima elemenata u nizu koji su jednaki
minimalnoj vrednost
broj = 0;//pocetna vrednost brojaca je uvek nula
for (int i = 0; i < niz.Length; i++)
{
if (niz[i] == min)
broj ++;
}
//nalazenje srednje vrednosti ne-negativnih elemenata u nizu
sv = 0;
int br = 0;//brojack koji broji takve elemente
for (int i = 0; i < niz.Length; i++){
if (niz[i] % 2 == 0){
sv += niz[i];
br++;
}
}
sv = sv / br;
}
static void Main(string[] args)
{
int n, broj=0;
float sv=0;
Console.WriteLine("Uneti dimenziju niza");
n = Convert.ToInt32(Console.ReadLine());
int[] niz = new int[n];
Console.WriteLine("Uneti elemente niza");
unos(niz);
izracunavanje(niz, ref broj, ref sv);

}
}

Console.WriteLine("Broj = {0}, srvr = {1}", broj, sv);


Console.ReadKey();

OOP vebe eljko Jovanovi


VEBE 03 OSNOVNI KONCEPTI OOP
// klasa kao struktura

//kompletna klasa
class Auto {

class Auto {
public int godiste;
public String boja;
public String ostecenje;

private int godiste;


private string boja;
protected string ostecenje;

};

public void start();


public int ubrzanje();
public void stop();
};

Osnovni koncepti OOP


Apstrakcija
Enkapsulacija
Nasleivanje
Polimorfizam

Apstrakcija

Postupak kojim se unutranja sloenost objekta skriva od spoljnjeg sveta.


Postupak kreiranja jednostavne reprezentacije neeg komplikovanog.
Postoje dve strane svakog objekta:
o ono to radi: to je obino poznato
o nain na koji radi: koji je obino nepoznat
Zavisi od perspektive korisnika
Iterativni proces: da bi se pronaao najbolji i najtaniji opis objekta, kao reenje za dati
problem, obino je potrebno proi nekoliko koraka.

Na primer: napraviti aplikaciju koja e se koristiti u bibliotekama


-

ta su elementi knjige?
Iz perspektive bibliotekarke:
naslov, autor, isbn broj, kategorija kojoj knjiga pripada.
Njena perspektiva je odreena njenim poslom.

Iz perspektive grafikog urednika:


vrsta korienja, tematika knjige (zbog dizajna omota)

OOP vebe eljko Jovanovi

Klasifikacija

Koren rei klasifikacija je klasa.


Obrazovanje klase = sistematsko ureivanje informacije u smislenu celinu.

Npr. Svi automobili imaju slina ponaanja (njima se moe upravljati, mogu se zaustaviti, ubrzati..)
i zajednike atribute (imaju volan, motor...).
Re Automobil se koristi za sve objekte koji dele ta zajednika ponaanja i atribute.
Konkretan objekat bi bio npr:
Opel Astra, registarskih tablica: BG 123, bele boje.

Pisanje progama u OOP: klasifikovanje razliitih koncepata svojstvenih nekom problemu i


njegovom reenju, a zatim modeliranje tih klasa u programskom jeziku.

Enkapsulacija (uaurenje)

Osnovni koncept na kome poiva objektna orijentisanost.


Softverska tehnika kojom se povezuju podaci i metode (radnje) koje se odnose na te
podatke u jednu celinu.
Podrazumeva da korisnici nekog objekta ne mogu menjati unutranja stanja i metode
objekata. Samo internim metodama objekata je omogueno da pristupe tim stanjima, dok
svaki objekat omoguava spoljnim korisnicima da pristupe i koriste njegove javne metode.
Skrivanje informacija
Smanjuje sloenost sistema
Dva bitna aspekta uaurenja:
objedinjavanje podataka i funkcija u jedinstven entitet (klasa)
kontrola mogunosti pristupa lanovima entiteta (modifikatori pristupa)

10

OOP vebe eljko Jovanovi

Klasa

Tip podataka koji sadri podatke i funkcije (metode).


Apstrakcija (uoptavanje) konkretnih objekata.
Definisanje klase:
[modifikator] class naziv_klase [: osnovna_lista] {telo_klase}

Modifikator

Public
Private
Internal
Protected
Protected
Internal

Primenljivo na
Tipove, lanove tipova
Tipove, lanove tipova
Tipove, lanove tipova
lanove tipova
lanove tipova

Opis
Vidljivo svuda, ak i izvan sklopa
Vidljivo samo u kodu koji pripada istom tipu
Vidljivo samo u kodu koji se nalazi u istom sklopu
Vidljivo samo u kodu koji pripada istom ili izvedenom tipu
Vidljivo samo u kodu koji se nalazi u istom sklopu ili u
izvedenoj klasi u drugom sklopu

Modifikatori mogu biti:


new, abstract, sealed
Ako vrsta vidljivosti klase nije izriito zadata, podrazumeva se internal.
Telo klase mogu initi: metode, svojstva, polja, konstruktori.
class Krug
{
//polja
double poluprecnik;
//metode
double Povrsina()
{
return 3.14 * poluprecnik * poluprecnik;
}
}

11

OOP vebe eljko Jovanovi

Polja i Svojstva

Svojstvo je ukrtanje logikog polja i fizikog metoda.


Ne koristi se na isti nain na koji se koriste polja: svojstvo izgleda kao polje, meutim
prevodilac automatski prevodi sintaksu za polja u pozive posebnih pristupnih metoda.
Pristupni metod get vraa vrednost odreenog tipa, dok metod set postavlja.
Svojstva samo za pisanje, za itanje...
Ogranienja svojstava:
Svojstvo ne moete da inicijalizujete pomou pristupnog metoda set
Svojstvo ne moete upotrebiti kao ref ili out parameter
Ne moete jednim iskazom deklarisati vie svojstava
Svojstva se ne mogu deklarisati sa kljunom rei const ili readonly
Unutar svojstva moete deklarisati pristupni metod get ili set ili oba.
Ne moe se deklarisati svojstvo koje je tipa void.

public class Koordinata


{
//polje
private double _x;
private double _y;
private double _z;
//svojstva
public double X
{
get { return _x; }
set { _x = value; }
}
public double Y
{
get { return _y; }
set { _y = value; }
}
public double Z
{
get { return _z; }
set { _z = value; }
}
//metoda
public void Resetuj()
{
X = Y = Z = 0.0;
}
}
class Program
{
static void Main()
{
// Inicijalizacija novog objekta.
Koordinata a = new Koordinata();
//Izmena svojstva
a.X = 200;
}

12

OOP vebe eljko Jovanovi

Auto-implemented properties (automatski definisana svojstva)


[modifikator] tip_svojstva naziv_svojstva {get; set;}

U C# 3.0 i kasnije, auto-implemented svojstva uinila su deklaraciju svojstava mnogo


konciznijom kada vie nije bila potrebna dodatna logika za pristupanje svojstvima.

Kada se svojstvo deklarie na nain prikazan u narednom primeru, kompajler kreira


privatno, anonimno polje (backing field) kome se moe pristupiti samo korienjem
pristupnih metoda svojstva get i set.

class Kupac
{
public double UkupnaKupovina { get; set; }
public string Ime { get; set; }
public int IdKupac { get; set; }
// .. Dodatne metode, dogaaji...
}
class Program2
{
static void Main()
{
// Inicijalizacija novog objekta.
Kupac cust1 = new Kupac();

//Izmena svojstva
cust1.UkupnaKupovina += 499.99;

NAPOMENA: Ne moete imati automatski definisano svojstvo koje ima samo naredbu get (ako ne
postoji pozadinsko polje, kako biste mu zadali vrednost?), ali naredba set moe biti privatna:
public int IdKupac { get; private set; }

4.Napravi klasu Osoba sa atributima ime,prezime i godina rodjenja. Kreirati Instancu klase Osoba i
iskoristiti ugraenu metodu predstaviSe().
NAPOMENA: Reenje demonstrirano u C++ i C# programskim jezicima!!!

//

C++

#include <iostream.h>
#include <string.h>
#define DIM 20
class Osoba{
public:
void PredstaviSe();
void setIme(char i[]){strcpy(ime, i);}
void setPrezime(char p[]){strcpy(prezime, p);}
void setGodiste(int g){godiste = g;}
char* getIme(){return ime;}
char* getPrezime(){return prezime;}

13

OOP vebe eljko Jovanovi


int getGodiste(){return godiste;}
private:
char ime[20];
char prezime[40];
int godiste;
};
void Osoba::PredstaviSe(){
// bez upotrebe get metoda
cout<<"Pozdrav svima!!!"<<endl;
cout<<"Ja sam "<<ime<<" "<<prezime<<" i "<<godiste<<". sam
godiste !!!"<<endl<<endl;
};
void main(){
Osoba o;
o.setIme("Pera");
o.setPrezime("Peric");
o.setGodiste(1990);
o.PredstaviSe();
// preko get motode
cout<<"Van metode ispis godista :"<<o.getGodiste()<<endl;
}

//

C#

class Osoba
{
private string ime;
public string Prezime{ get; set; }
public int Godiste { get; set; } //kako pristupiti da je {get;private set;}
public string Ime
{
get { return ime; }
set { ime = value; }
}
public void PredstaviSe(){
Console.WriteLine("Pozdrav svima!!!");
Console.WriteLine("Ja sam " + ime + " " + Prezime + " i " + Godiste + ".
sam godiste !!!");
}
};
class Program
{
static void Main(string[] args)
{
Osoba o = new Osoba();
o.Ime = "Pera";
o.Prezime = "Peric";
o.Godiste = 1990;
}

o.PredstaviSe();

14

OOP vebe eljko Jovanovi


ZADATAK. Definisati klasu Automobil sa sledeim javnim podacima lanovima (atributima,
poljima): marka, godina proizvodnje, cena i registarski broj i funkcijama lanicama za unos i ispis
podataka o automobilu.
Napisati glavni program u kome se unose podaci o dva automobila i ispisuju podaci o automobilu
koji ima veu cenu, korienjem funkcije.
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Text;

namespace KonzolnaAplikacijaAutomobil
{
class Program
{
public class Automobil
{
//podaci clanovi
public string marka;
public int godP;
public double cena;
public string regB;
//funkcija clanica klase-metoda
public void unos()
{
Console.WriteLine("Unesi podatke o automobilu:");
Console.WriteLine("Marka automobila:");
marka = Console.ReadLine();
Console.WriteLine("Godina proizvodnje:");
godP = int.Parse(Console.ReadLine());
Console.WriteLine("Cena:");
cena = double.Parse(Console.ReadLine());
Console.WriteLine("Registarski broj:");
regB = Console.ReadLine();
}
//funkcija clanica klase-metoda
public void ispis()
{
Console.WriteLine("Marka automobila: {0}", marka);
Console.WriteLine("Godina proizvodnje: {0}", godP);
Console.WriteLine("Cena automobila: {0}", cena);
Console.WriteLine("Registarski broj: {0}", regB);
Console.ReadLine();
}
}
// globalna funkcija van klase
static public void vecaCena(Automobil a, Automobil b)
{
Console.WriteLine("Automobil koji ima vecu cenu ima sledece podatke:");
if (a.cena > b.cena)
a.ispis();
else b.ispis();
}

15

OOP vebe eljko Jovanovi


static void Main(string[] args)
{
Automobil a = new Automobil();
Automobil b = new Automobil();
a.unos();
b.unos();
vecaCena(a, b);
}
}

ZADATAK. Definisati klasu Drzava, koja sadri:


Privatne podatke clanove:
- naziv drzave (maksimalno 30 znakova);
- ime glavnog grada (maksimalno 20 znakova);
- povrsina drzave i
- ukupan broj stanovnika;
Javne metode clanice:
- metode za unos i ispis podataka o drzavi. Prilikom ispisa ispisati i gustinu naseljenosti;
- metoda koja odreuje gustinu naseljenosti drave (broj stanovnika/km).
Definisati sledee globalne metode:
- metodu u kojoj se po gustini naseljenosti vri sortiranje n (n<10) zadatih drzava u rastuem
poretku;
- metodu u kojoj se ispisuju podaci o onoj dravi koja ima najmanju gustinu naseljenosti.
using
using
using
using

System;
System.Collections.Generic;
System.Linq;
System.Text;

namespace KlasaDrzava
{
class Program
{
public class Drzava
{
private string naziv;
private string glGrad;
private double povrsina;
private long brStanov;
/*

Ne koriste se get i set pristupnici jer polja nisu koriena u glavnoj funkciji
* ve u samoj klasi
*
public string GetSetNaziv
{
get
{
return naziv;
}
set
{
naziv = value;
}
}

*/

16

OOP vebe eljko Jovanovi


public void unos()
{
Console.WriteLine("Unesi podatke o drzavi:");
Console.WriteLine();
Console.Write("Naziv drzave: ");
naziv = Console.ReadLine(); //unos stringa naziv
Console.Write("Glavni grad: ");
glGrad = Console.ReadLine(); //unos stringa glGrad
Console.Write("Povrsina: ");
povrsina = double.Parse(Console.ReadLine()); // double.Parse - konvertovanje stringa u

double

Console.Write("Broj stanovnika: ");


brStanov = long.Parse(Console.ReadLine()); // long.Parse - konvertovanje stringa u long

public void ispis()


{
Console.WriteLine("Naziv drzave: {0}", naziv);
Console.WriteLine("Glavni grad: {0}", glGrad);
Console.WriteLine("Povrsina: {0}", povrsina);
Console.WriteLine("Broj stanovnika: {0}", brStanov);
Console.WriteLine("Gustina naseljenosti je: {0}", this.Gustina());
Console.WriteLine();
}
public double Gustina() { return brStanov / povrsina; }

}
static public void Razmeni(Drzava[] niz, int a, int b)
{
Drzava t = niz[a];
niz[a] = niz[b];
niz[b] = t;
}
static public void Sortiranje(Drzava[] niz, int n)
{
for (int i = 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
{
if (niz[i].Gustina() > niz[j].Gustina())
{
Razmeni(niz, i, j);
}
}
}
static public void MinGustina(Drzava[] niz, int n)
{
double min = niz[0].Gustina();
int mini = 0;
for (int i = 1; i < n; i++)
{
if (min > niz[i].Gustina())
{
min = niz[i].Gustina();
mini = i;
}
}

Console.WriteLine("Podaci o drzavi sa minimalnom gustinom naseljenosti su: ");

17

OOP vebe eljko Jovanovi


niz[mini].ispis();
Console.WriteLine();
}

static void Main(string[] args)


{
int n;
Console.WriteLine("Broj drzava n (n<10): ");
n = int.Parse(Console.ReadLine());
Drzava[] niz = new Drzava[n];
for (int i = 0; i < n; i++)
{
niz[i] = new Drzava();
niz[i].unos();
}
Console.WriteLine();
Sortiranje(niz, n);
Console.WriteLine("Spisak unetih drzava: ");
Console.WriteLine();
for (int i = 0; i < n; i++)
{
niz[i].ispis();
}
Console.WriteLine();
MinGustina(niz, n);
Console.ReadKey();
}

18

OOP vebe eljko Jovanovi


VEBE 04 POJAM KONSTRUKTORA

Konstruktor

Metoda klase koja se izvrava kada se kreira objekat odreene klase.


Ima isto ime kao i klasa, nema povratnu vrednost (ni void) i obino inicijalizuje
elemente novog objekta.
Moe biti : podrazumevani ili parametarizovani
Poziva se od strane new operatora, odmah nakon alokacije memorije za novi objekat.
U konstruktoru bi trebalo da se rade samo jednostavne inicijalizacije
Konstruktor moe primiti jedan ili vie parametara koji se koriste za inicijalizaciju
polja.
Ako se u klasi deklarie bar jedan konstruktor, kompajler nee generisati podrazumevani
konstruktor.
Sva polja koja nisu inicijalizovana u korisniki definisanom konstruktoru zadravaju
svoju podrazumevanu inicijalizaciju.
Za jednu klasu moe se definisati vie konstruktora ( lista parametara svakog od njih
mora biti jedinstvena, ili po broju ili po tipu parametara - razliiti potpis)
PRIMER: Podrazumevani (default) konstruktor

class Student
{
string _ime;
string _brojIndeksa;
//public Student(){}
/* default konstruktor; podrazumeva se da postoji
(automatski se generise) ukoliko nije eksplicitno naveden konstruktor*/

}
class Program
{
public static void Main(string[] args)
{
/*kreira se objekat pozivom podrazumevanog konstruktora*/
Student student = new Student();
}
}

19

OOP vebe eljko Jovanovi


PRIMER: Reimplementacija podrazumevanog konstruktora kao i primer za parametarizovani
class Student
{
private string _ime;
private string _brojIndeksa;
public Student()
{
_brojIndeksa = "0000/2012";
}
}
class Program
{
static void Main(string[] args)
{
Student s = new Student();
}
}

//parametarizovani konstruktor
class Student
{
private string _ime;
private string _brojIndeksa;
public Student(string i,string bi)
{
_ime = i;
_brojIndeksa = bi;
}
}
class Program
{
public static void Main(string[] args)
{
Student student = new Student();
/* greska; ispravno je pozvati ukoliko u
klasi postoji eksplicitno naveden
podrazumevajuci konstruktor ili ne
postoji ni jedan*/
Student student1 = new
Student("Pera","123/2000");
}
}

PRIMER: promena vrednosti atributa kreirane instance klase


class Program
{
public static void Main(string[] args)
{
// deklaracija objekta
Student student1 = new Student("Pera","123/2000");
student1._ime = "Mika"; // greka: nije mogue prisupiti
// privatnom polju _ime klase Student

}
}

// prethodnom primeru dodati svojstvo Ime kojim ce se omoguciti


// promena polja _ime

20

OOP vebe eljko Jovanovi


PREGLED OSNOVNIH ELEMENATA KLASE NA PRIMERU KLASE STUDENT:
class Student
{
// polja klase
string _ime;
string _brojIndeksa;
double _prosecnaOcena;
int _generacija;
//svojstvo
public int Generacija
{
get{ return _generacija;}
set {_generacija=value;}
}
// podrazumevani konstruktor
public Student()
{
_ime = "";
_brojIndeksa = "0000/2012";
}
// parametarizovani konstruktor 1
public Student(string ime, string bi)
{
_ime = ime;
_brojIndeksa = bi;
}
// parametarizovani konstruktor 2
public Student(string bi)
{
_brojIndeksa = bi;
}
// metoda
public void PromeniBrojIndeksa(string bi)
{
_brojIndeksa = bi;
}
}

21

OOP vebe eljko Jovanovi


ZADATAK 1: Napraviti klasu Televizor da ima:
Atribute
_jacinaTona. Poetna vrednost za jacinu tona je 0 (smatra se da je ton iskljucen tj. 0)
ukljucen. Poetna vrednost za atribut ukljucen je false (televizor ugasen).
Metode
pojacajTon, pojacava ton televizora za jedan.
smanjiTon, smanjuje ton televizora za jedan.
ukljuci, postavlja vrednost atributa ukljucen na true (tj. ukljucuje televizor)
iskljuci, koja postavlja vrednost atributa ukljucen na false (tj. iskljucuje televizor)
daLiJeUkljucen, vraca vrednost atributa ukljucen
vratiJacinuTona, koja vraca trenutnu vrednost jacine tona
ispisi, ispisuje na ekranu trenutne vrednosti oba atributa uz odgovarajucu poruku
Napraviti klasu TestTelevizor koja u main metodi kreira jedan objekat klase Televizor i poziva
njegove metode: pojacajTon, ispisi, iskljuci.
Dodeliti atributu jacinaTona vrednost. Diskutovati o svojstvima.
class Televizor{
int _jacinaTona;
bool ukljucen = false;
public int jacinaTona {
get { return _jacinaTona; }
set { _jacinaTona = value; }
}
public void pojacajTon() {
++_jacinaTona;
}
public void smanjiTon() {
--_jacinaTona;
}
public void iskljuci() {
ukljucen = false;
}
public void ukljuci() {
ukljucen = true;
}
public Boolean daLiJeUkljucen() {
return ukljucen;
}
public int vratiJacinuTona() {
return jacinaTona;
}
public void ispisi() {
Console.WriteLine("\n
Televizor je ukljucen: " + ukljucen);
Console.WriteLine("
Jacina tona je: "+ jacinaTona);
}

class Program
{
static void Main(string[] args)
{
Televizor t = new Televizor();
t.ispisi();
//Televizor je ukljucen: False
//Jacina tona je: 0
t.ukljuci();
t.ispisi();
//Televizor je ukljucen: True
//Jacina tona je: 0
t.jacinaTona = 12;
t.pojacajTon();
t.ispisi();
//Televizor je ukljucen: True
//Jacina tona je: 13
Console.ReadLine();
}
}

NAPOMENA : static svojstvo


Svaka klasa moe imati atribut koji je zajedniki za sve instance te klase.
Definie se kljunom rei static
Promena tog atributa u bilo kojoj instanci klase menja taj atribut svim njenim instancama
Vrednost atributa se dohvata preko imena klase a ne preko njene instance

22

OOP vebe eljko Jovanovi


ZADATAK 2 : Definisati klasu Krug da ima:
Privatna Polja: _x, _y (koordinate centra kruga) : integer
Javno svojstvo (auto-property): R (poluprenik kruga) : integer

Javno static svojstvo (auto-property): broj, privatnog set svojstva: integer

Javna svojstva (za polja _x i _y) X i Y : integer

Javni podrazemevani konstruktor koji inicijalizuje vrednosti polja X, Y i R na 0,


Javni parametarizovani konstruktor za parametre (X, Y, R)

NAPOMENA: u okviru oba konstruktora podesiti polje broj tako da predstavlja broj kreiranih
instanci klase Krug u glavnom delu programa.

Javnu metodu: povrsina() : void, koja rauna povrinu i na ekranu ispisuje poruku sedeeg
formata: Povrsina kruga parametara X = 1, Y = 2, R = 3 je: 28.26

U glavnom delu programa (main) :


Ispisati vrednost polja broj
Kreirati instacu klase Krug : a, pomou podrazumevanog konstruktora
Ispisati vrednost polja broj
Kreirati instacu klase Krug : b, pomou parametarizovanog konstruktora
Ispisati vrednost polja broj
Dodeliti vrednosti poljima objekta a preko kreiranih svojstava.
Demostrirati poziv metode povrsina na ispisu povrina Krugova a i b
Koje e vrednosti ispisivati na monitoru prilikom ispisa vrednosti polja broj u prethodno
definisanim trenutcima.
Mogu li sledei kodovi izvriti u okviru main dela programa (objasniti):

Krug.broj = 5;
a.broj = 5;

REENJE:
class Krug
{
private int _x;
private int _y;
public int R { get; set; }
public static int broj {get; private set;}
public int X
{
set {_x = value;}
get {return _x;}
}
public int Y
{
set { _y = value; }
get { return _y; }
}

23

OOP vebe eljko Jovanovi


public Krug(int x, int y, int r)
{
_x = x;
_y = y;
R = r;
broj++;
}
public Krug()
{
_x = 0;
_y = 0;
R = 0;
broj++;
}
public void povrsina()
{
Console.WriteLine("Povrsina kruga parametara \nX = "
+ _x + ", Y = " + _y + ", R = "+ R +" je: "+ Math.Pow(R, 2) * 3.14);
}

}
class Program
{
static void Main()
{
Console.WriteLine("static broj = " + Krug.broj);
Krug a, b = new Krug(3, 5, 7);
Console.WriteLine("static broj = " + Krug.broj);

// 0
// 1

a = new Krug();
a.X = 1;
a.Y = 2;
a.R = 3;
Console.WriteLine("static broj = " + Krug.broj);

// 2

a.povrsina();
b.povrsina();
// Krug.broj = 5;
// a.broj = 5;
}

// GRESKA: set svojstvo je private


// GRESKA: pristupa se preko imena klase, NE instance

Console.ReadKey();

24

OOP vebe eljko Jovanovi


VEBE 05

Nasleivanje
Jedan od osnovnih koncepata OOP
Na osnovu postojee klase (bazna klasa) izvodi se nova (izvedena) koja nasleuje sve
lanove (polja i metode)
Odnos meu klasama a ne meu objektima
Klasa System.Object je osnovna za sve klase
Grupe koje su povezane nasleivanjem formiraju strukturu koja se naziva hijerarhija klasa

Vrste nasleivanja
Direktno

Indirektno

Sve izmene u baznoj klasi se direktno odraavaju na izvedene klase


(obrnuto ne vai)
Jednu baznu klasu moe da nasledi vie izvedenih klasa.
C# podrava samo jednostruko nasleivanje: jedna klasa moe da nasledi
najvie jednu baznu klasu.

25

OOP vebe eljko Jovanovi

Implementacija
class BaznaKlasa
{

}
class IzvedenaKlasa:BaznaKlasa
{

Postize se pomou znaka dve take : i imena osnovne klase


Izvedena klasa nasleuje sve lanove bazne klase a ima pristup samo onima
koji nisu private.
Izvedena klasa ne nasleuje konstruktor i destruktor.
Kljune rei: protected i sealed

26

OOP vebe eljko Jovanovi

PRIMER 1:
Definisati klasu Osnovna sa :
privatnim poljem int _a,
zastienim poljem int _b,
javnim poljem int _c.
Javnom metodom void osnovnaMetoda: podeava vrednosti svih polja na 50
Definisati klasu Izvedena, izvedenu iz klase Osnovna sa :
privatnim poljem int _d,
zastienim poljem int _e,
javnim poljem int _f.
Javnom metodom void izvedenaMetoda: podeava vrednosti svih polja na 80
U glavnom delu programa:
Kreirati objekat osnovne klase
Ispisti vrednosti dostupnih polja osnovne klase
Pozvati metodu osnovnaMetoda()
Ispisti vrednosti dostupnih polja osnovne klase
Kreirati objekat izvedene klase
Ispisti vrednosti dostupnih polja izvedene klase
Pozvati metodu osnovnaMetoda()
Ispisti vrednosti dostupnih polja izvedene klase
Pozvati metodu izvedenaMetoda()
Ispisti vrednosti dostupnih polja izvedene klase
Kako izgleda ispis u konzoli

27

OOP vebe eljko Jovanovi

REENJE:
class Osnovna
{
private int _a;
protected int _b;
public int _c;
public
{
//
//
_a

void osnovnaMetoda()
iz metode osnovne klase se moze raditi sa:
svim poljima osnovne klase
= _b = _c = 50;

// u osnovnoj klasi se ne vidi nista iz izvedenih klasa


// _f = 50; // GRESKA
}

class Izvedena:Osnovna
{
private int _d;
protected int _e;
public int _f;
public
{
//
//
_d

void izvedenaMetoda()
iz metode izvedene klase se moze raditi sa:
svim poljima izvedene klase
= _e = _f = 80;

// public i protected clanovima osnovne klase


_b = _c = 80;
// private clanovima se ne moze pristupiti
// _a = 80; // GRESKA
}

28

OOP vebe eljko Jovanovi


class Program
{
static void Main(string[] args)
{
// kreiranje objekta osnovne klase
Osnovna o = new Osnovna();
// dostupna polja iz osnovne klase
Console.WriteLine("Iz osnovne C = "+ o._c);

// C = 0

o.osnovnaMetoda();
Console.WriteLine("Iz osnovne C = " + o._c);

// C = 50

// kreiranje objekta izvedene klase


Izvedena iz = new Izvedena();
// dostupna polja iz izvedene klase
Console.WriteLine("Iz izvedene C = " + iz._c);
Console.WriteLine("Iz izvedene F = " + iz._f);

// C = 0
// F = 0

iz.osnovnaMetoda();
Console.WriteLine("Iz izvedene C = " + iz._c);
Console.WriteLine("Iz izvedene F = " + iz._f);

// C = 50
// F = 0

iz.izvedenaMetoda();
Console.WriteLine("Iz izvedene C = " + iz._c);
Console.WriteLine("Iz izvedene F = " + iz._f);

// C = 80
// F = 80

Console.ReadKey();
}

Nasleivanje je odnos meu klasama, a ne objektima. To znai da odnos vai za sve objekte iz te
klase.

29

OOP vebe eljko Jovanovi

VEBE 06

Nasleivanje - Konstruktor izvedene klase

Konstruktor izvedene klase mora da pozove konstruktor svoje bazne klase.


Za pozivanje konstruktora bazne klase uvek se koristi kljuna re base.
Prvo se izvrava konstruktor bazne klase pa tek onda konstruktor izvedene
Konstruktor izvdene klase moe da inicijalizuje sva polja izvedene klase kao i dostupna
polja svih osnovnih klasa do vrha stabla iz kojeg potie.

30

OOP vebe eljko Jovanovi


class Osnovna
{
private int _x;
public Osnovna(int x)
{
// inicijalizacija polja osnovne klase
_x = x;
}

}
class Izvedena1 : Osnovna
{
protected int _y;

public Izvedena1(int x, int y) : base(x)


{
// inicijalizacija polja osnovne klase
// _x = x; // GRESKA, private atribut, da je protectet bilo bi OK
// inicijalizacija polja izvedene klase
_y = y;

}
}
class Izvedena2 : Osnovna
{
private String _z;

public Izvedena2(int x, String z) : base(x)


{
// inicijalizacija polja osnovne klase
// _x = x; // GRESKA, private atribut, da je protectet bilo bi OK
// inicijalizacija polja izvedene klase
_z = z;
}
}
class Izvedena3 : Izvedena1
{
private String _w;
public Izvedena3(int x, int y, String w) : base(x,y)
{
// inicijalizacija polja osnovne klase
// _x = x; // GRESKA, private atribut, da je protectet bilo bi OK
// inicijalizacija polja klase Izvedena1
_y = y;
// OK, protected atribut
// inicijalizacija polja klase Izvedena3
_w = w;
}

PRIMER 1:
Definisati klasu Osoba sa:
Protected poljima ime i prezime
Parametarizovanim konstruktorom
Public metodom void podaciOsobe(): ispisuje podatke o Osobi

31

OOP vebe eljko Jovanovi

Definisati klasu Student sa:


Private poljem brojIspita
Parametarizovanim konstruktorom
Public metodom void podaciStudenta(): ispisuje podatke o Studentu
U glavnom delu programa:
Kreirati instancu klase Osoba pomou parametarizovanog konstruktora
Ispitati podatke o Osobi
Kreirati instancu klase Student pomou parametarizovanog konstruktora
Ispitati podatke o Studentu pomou metode podaciOsobe
Ispitati podatke o Studentu pomou metode podaciStudenta
ta e se dobiti kao rezultat izvrenja programa
REENJE:
public class Osoba
{
protected string ime;
protected string prezime;
public Osoba(string i, string p)
{
ime = i;
prezime = p;
}
public void podaciOsobe()
{
Console.WriteLine(ime + " " + prezime);
}
}

public class Student : Osoba


{
private int brIspita;
public Student(string i, string p, int b)
: base(i, p)
{
brIspita = b;
}

public void podaciStudenta()


{
// kako ispisati podatke iz osobe da su ime i prezime private
Console.WriteLine(ime + " " + prezime + " " + brIspita);
}

32

OOP vebe eljko Jovanovi

class Glavna
{
static void Main(string[] args)
{
Osoba o = new Osoba("Pera", "Peric");
o.podaciOsobe();
// Pera Peric
Student s = new Student("Mika", "Mikic", 11);
s.podaciOsobe();
s.podaciStudenta();

// Mika Mikic
// Mika Mikic 11

Console.ReadKey();
}

33

OOP vebe eljko Jovanovi

Kompatibilnost objektnih tipova


Inicijalizacija instance klase konstruktorom druge klase ???
Poto su odreene klase unutar nekog stabla nasleivanja postoji interesantna
mogunost inicijalizacije instance klase konstruktorom druge klase.
Odreeni odnosi su dozvoljeni a odreeni nisu.
PRIMER :
Za sledeu strukturu klasa prikazanu na dijagramu obeleiti ta nije dozvoljeno od
sledeih poziva konsturuktora pod pretpostavkom da su svi parametarizovani
konstruktori definisani za sva polja klasa po redu pojavaljivanja od osnovne klase
ka izvedenim.

Osoba o = new Osoba("pera", "peric", 10);


Radnik r = new Radnik("Mika", "mikic", 10, 10);
Direktor d = new Direktor("ivan", "ivic", 10, 10, 10);

Osoba o1 = new Radnik("Mika", "mikic", 10, 10);


Osoba o2 = new Direktor("ivan", "ivic", 10, 10, 10);
Osoba o3 = new Osoba("Mika", "mikic", 10, 10);

Radnik r1 = new Osoba("pera", "peric", 10);


Radnik r2 = new Radnik("pera", "peric", 10);
Radnik r3 = new Direktor("ivan", "ivic", 10, 10, 100);

Direktor d1 = new Osoba("pera", "peric", 10);


Direktor d2 = new Radnik("Mika", "mikic", 10, 10, 10);
Direktor d3 = new Direktor("Mika", "mikic", 10, 10);

34

OOP vebe eljko Jovanovi

REENJE:
o
r
d

// OK - konstruktor odgovarajuce klase


// OK - konstruktor odgovarajuce klase
// OK - konstruktor odgovarajuce klase

o1 // OK - konstruktor izvedene klase


o2 // OK - konstruktor izvedene klase
o3 // GRESKA - 4 argumenta, treba 3
r1 // GRESKA - konstruktor osnovne klase
r2 // GRESKA - 3 argumenta, treba 4
r3 // OK - konstruktor izvedene klase
d1 // GRESKA - konstruktor osnovne klase
d2 // GRESKA - konstruktor osnovne klase
d3 // GRESKA - 4 argumenta, treba 5

NAPOMENA:
parametari konstruktora se moraju poklapati po broju, tipu i redosledu
u objekat osnovne klase MOE se smestiti objekat izvedene klase
u objekat izvedene klase NE MOE se smestiti objekat osnovne klase

35

OOP vebe eljko Jovanovi

VEBE 07

Polimorfizam
Metoda koja je implementirana u osnovnoj (baznoj) klasi moe da bude implementirana
na vie razliitih naina u razliitim izvedenim klasama

Razliiti objekti mogu razliito reagovati na istu poruku


Osnovne klase definiu i implementiraju virtuelne metode, a izvedene klase
reimplementiraju te metode po potrebi

Da bi se ukljuio polimorfizam za izabrani metod, upotrebljava se kljuna re virtual


Reimplementiranje (redefinisanje) proces implementacije virtuelnih metoda u
izvedenim klasama. Kod reimplementirane metode se koristi kljuna re override.

public class Osnovna


{
public virtual void PromeniKorisnickoIme(){. . .}
}
public class Izvedena : Osnovna
{
public override void PromeniKorisnickoIme(){. . .}
}

36

OOP vebe eljko Jovanovi

Pravila

Nije dozvoljeno deklarisati privatan metod sa kljunom rei virtual ili override

Dva metoda moraju biti identina ( isto: ime, tipovi parametara i tip povratne vrednosti )

Isti pristup (oba javna,..)

Reinicijalizovati (nadjaati) se moe samo virtuelni metod

Ako izvedena klasa ne oznai metod sa override, ona tada ne nadjaava metod bazne klase

Nije dozvoljeno eksplicitno zajedno koristiti rei override i virtual

37

OOP vebe eljko Jovanovi


ZADATAK 1: Za prikazani dijagram klasa uraditi sledee:
Definisati klasu Raun sa:
Zatienim poljem stanje : double
Svojstvo Stanje: double, privatnog set svojstva
metodom uplata (double) : void
virtual metodom isplata (double) : void
override ugraene metode ToString
Definisati klasu Dinarski sa:
override metodom isplata (double) : void, provizija pri isplati 5%
override ugraene metode ToString
Definisati klasu Devizni sa:
override metodom isplata (double) : void, provizija pri isplati 6%
override ugraene metode ToString
U glavnom delu programa uraditi:
Kreirati objekta klase Dinarski
Uplatiti 50000 din na raun
Probati uplatu preko svojstva Stanje
Ispisati stanje na raunu toString metodom
Ispisati stanje na raunu preko svojstva Stanje

Kreiranje objekta klase Devizni


Uplatiti 1000 eura na raun metodom uplata
Probati uplatu preko svojstva Stanje
Ispisati stanje na raunu toString metodom
Ispisati stanje na raunu preko svojstva Stanje

Isplatiti sa dinarskog rauna 10000 din


Ispisati stanje na raunu toString metodom
Ispisati stanje na raunu preko svojstva Stanje
Isplatiti sa deviznog rauna 200 eura metodom uplata
Ispisati stanje na raunu toString metodom
Ispisati stanje na raunu preko svojstva Stanje

38

OOP vebe eljko Jovanovi


REENJE: KOD
public class Racun
{
protected double stanje;
public double Stanje {
get { return stanje; }
private set { stanje = value; }
}
// klasicna uplata bez provizije
public void uplata(double u)
{
stanje += u;
}
// klasicna isplata bez provizije
public virtual void isplata(double i)
{
}

stanje -= i;

// overide ugradjene metode ToString()


public override string ToString()
{
return ("RACUN = " + stanje);
}
}
public class Dinarski : Racun
{
// isplata sa provizijom od 5 %
public override void isplata(double i)
{
double provizija = 0.05;
// poziv metode isplata osnovne klase
base.isplata(i);
stanje -= i * provizija;
}

// overide ugradjene metode ToString()


public override string ToString()
{
return ("DINARSKI = " + stanje+ " dinara");
}

public class Devizni : Racun


{
// isplata sa provizijom od 6 %
public override void isplata(double i)
{
double provizija = 0.06;
// poziv metode isplata osnovne klase
base.isplata(i);

39

OOP vebe eljko Jovanovi


stanje -= i * provizija;
}

// overide ugradjene metode ToString()


public override string ToString()
{
return ("DEVIZNI = " + stanje + " eura");
}

class Glavna
{
static void Main(string[] args)
{
Dinarski din = new Dinarski();
Console.WriteLine(din);
Console.WriteLine(din.Stanje);

// DINARSKI = 0 dinara
// 0 // OK, public get

Devizni dev = new Devizni();


Console.WriteLine(dev);
Console.WriteLine(din.Stanje);

// DEVIZNI = 0 eura
// 0 // OK, public get

din.uplata(50000);
// din.Stanje += 50000;
Console.WriteLine(din);
Console.WriteLine(din.Stanje);

// GRESKA, private set


// DINARSKI = 50 000 dinara
// 50 000 // OK, public get

dev.uplata(1000);
// dev.Stanje += 1000;
Console.WriteLine(dev);
Console.WriteLine(dev.Stanje);

// GRESKA, private set


// DEVIZNI = 1 000 eura
// 1 000 // OK, public get

din.isplata(10000);
Console.WriteLine(din);
Console.WriteLine(din.Stanje);

// DINARSKI = 39 500 dinara


// 39 500 // OK, public get

dev.isplata(200);
Console.WriteLine(dev);
Console.WriteLine(dev.Stanje);
Console.ReadKey();
}

40

// DEVIZNI = 788 eura


// 788 // OK, public get

OOP vebe eljko Jovanovi


VEBA: Kreirati globalne metode:

void ispis(Racun [] a, int n) ispisuje podatke o svim raunima

void isplata(Racun [] a, int n, int iznos) vri isplatu prosleenog iznosa sa svih rauna u
nizu a.

U glavnom programu kreirati nekoliko razliitih tiova rauna (Dinarski, Devizni) i ubaciti iz u niz
Racuna (pokazivaa na osnovnu klasu). Pozvati metodu ispis, pa isplata da isplati po 100 sa svih
rauna. Nakon toga pozvati ponovo metodu ispit da se ispiu podaci svih rauna i proveriti da li je
pravilno izraunata provizija pri isplati sa dinarskih i deviznih rauna.
REENJE:
class Program
{
static void Main(string[] args)
{
Racun r0 = new Dinarski();
Racun r1 = new Dinarski();
Racun r2 = new Devizni();
Racun r3 = new Devizni();
r0.uplata(1000);
r1.uplata(1000);
r2.uplata(1000);
r3.uplata(1000);
Racun[] niz = new Racun[4];
niz[0]
niz[1]
niz[2]
niz[3]

=
=
=
=

r0;
r1;
r2;
r3;

ispis(niz, 4);
isplata(niz, 400);
ispis(niz, 4);
Console.ReadKey();
}
public static void ispis(Racun [] niz, int n) {
Console.WriteLine("PREGLED RACUNA");
for (int i = 0; i < n; i++)
Console.WriteLine(niz[i]);
}
public static void isplata(Racun[] niz, double iznos) {
foreach (Racun pom in niz)
pom.isplata(iznos);
}
}

41

OOP vebe eljko Jovanovi


PREGLED RACUNA
DINARSKI RACUN: 1000
DINARSKI RACUN: 1000
DEVIZNI RACUN: 1000
DEVIZNI RACUN: 1000
PREGLED RACUNA
DINARSKI RACUN: 580
DINARSKI RACUN: 580
DEVIZNI RACUN: 576
DEVIZNI RACUN: 576

42

OOP vebe eljko Jovanovi

VEBE 08

Polimorfizam new i override

NEW se moe koristiti kao:


o operator (za kreiranje objekta i poziv konstruktora) i kao
o modifikator (za eksplicitno skrivanje lanova nasleenih iz bazne klase)

Potpis metode ine: ime metode i broj i tipovi njegovih parametara

Kada bazna i izvedena klasa imaju metode sa istim potpisom, potrebno je da se kod
izvedene upotrebi kljuna re new.

Nije neophodno (ukoliko se ne navede, generisae se upozorenje).

public class Osoba


{
public string username;
public void PromeniKorisnickoIme(string new_username) { . . .}
}
public class Student : Osoba
{
new public void PromeniKorisnickoIme (string username_new) { . . .}
}

NAPOMENA:

Medota osnovne klase nije obeleena kao virtualna i kao takva nije podlona promeni
implementacije u izvedenim klasama (ne ponaa se polimorfno) ve se novokreirana metoda
izvedene klase ponaa kao nova metoda

Korienje new modifikatora kod deklaracije koja nije nasleena, generie upozorenje.

43

OOP vebe eljko Jovanovi

Podsetnik:
Promenljiva tipa bazna klasa moe da referencira instance direktno ili indirektno
izvedenih klasa.

Osnovna osn = new Izvedena ();


Izvedena izv = new Izvedena ();
VANO:
Pri ovakvoj inicijalizaciji instance klasa postoji razlika da li je virtualna metoda
override-ovana ili
pregaena sa modifikatorom new

Greka je ukoliko se upotrebe u isto vreme kljune rei new i override.


New kreira novog lana sa istim imenom i dovodi do toga da originalni (iz bazne klase)

bude sakriven.
Override proiruje implementaciju nasleenog lana.

44

OOP vebe eljko Jovanovi


PRIMER : Demostracija razlike u radu metoda izvedenih klasa u zavisnosti od modifikatora
(override, new) pri naglaenoj virtual metodi osnovne klase.

new

override
public class Osnovna
{
public virtual void SomeMethod()
{
//print Osnovna
}
}
public class Izvedena : Osnovna
{
public override void SomeMethod()
{
//print Izvedena
}
}
//...
Osnovna b = new Izvedena ();
Izvedena d = new Izvedena ();

public class Osnovna


{
public virtual void SomeMethod ()
{
//print Osnovna
}
}
public class Izvedena: Osnovna
{
public new void SomeMethod ()
{
//print Izvedena
}
}
//...
Osnovna b = new Izvedena ();
Izvedena d = new Izvedena ();

b.SomeMethod();
d.SomeMethod();

b.SomeMethod ();
d.SomeMethod ();

IZLAZ:
Izvedena//pozvana metoda iz izvedene
Izvedena

IZLAZ:
Osnovna // pozvana metoda iz Osnovne
Izvedena

ZAKLJUAK:
Kada je u usnovnoj klasi metoda definisana kao virtualna onda ako se u izvedenoj
klasi njena implementacija:
proiri pomou override svaka instanca klase Izvedena (ne vano da li preko
Osnovne ili Izvedene klase) poziva metudu izvedene klase
pregazi pomou new svaka instanca klase Izvedene referencirana preko:
o Osnovne klase poziva metodu osnovne klase
o Izvedene klase poziva metodu izvedene klase

45

OOP vebe eljko Jovanovi

PRIMER: Demonstracija prikrivanja polja osnovne klase u izvedenim klasama


public class Osnovna
{
public static int x = 55;
public static int y = 22;
}
public class Izvedena1 : Osnovna
{
// Skriva polje x.
new public static int x = 100;
}
public class Izvedena2 : Izvedena1
{
// Skriva polje y.
new public static int y = 200;
static void Main()
{
// Prikazuje vrednost polja x svih instanci klase Osnovna:
Console.WriteLine(Osnovna.x);
// Prikazuje vrednost polja x svih instanci klase Izvedena1:
Console.WriteLine(Izvedena1.x);
// Prikazuje vrednost polja x svih instanci klase Izvedena2:
Console.WriteLine(Izvedena2.x);
// Prikazuje vrednost polja y svih instanci klase Osnovna:
Console.WriteLine(Osnovna.y);
// Prikazuje vrednost polja y svih instanci klase Izvedena1:
Console.WriteLine(Izvedena1.y);
// Prikazuje vrednost polja y svih instanci klase Izvedena2:
Console.WriteLine(Izvedena2.y);
}

Console.ReadKey();

}
/*IZLAZ:
55
100
100
22
22
200
*/

46

You might also like