Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 44

Razvoj aplikacija u programskom jeziku C#

Predavanja 2015./2016.

Osnove programskog jezika C# 2

10/31/16

Razvoj aplikacija u programskom jeziku C#

1 / 10

C# OOP

10/31/16

Razvoj aplikacija u programskom jeziku C#

Klase
Klasa fundamentalni konstrukt .NET platforme
Definicija vlastitog tipa koji se sastoji od podataka i funkcijama koje barataju tim podacima
(metode)

Grupiranjem funkcionalnosti i podataka u klasama moemo graditi modele koji


nalikuju entitetima koje sreemo u stvarnom ivotu
Primjer:
Auto
Stanje: Naziv, verzija, proizvoa, maksimalna brzina, datum
proizvodnje, trenutna brzina, trenutna akceleracija, je li klima upaljena...
Funkcionalnost: Stisni gas, stisni konicu, volan lijevo/desno, upali
klimu...

10/31/16

Razvoj aplikacija u programskom jeziku C#

Klase
Kljuna rije: class

class Car
{
// internal
}

Slijedi naziv tipa

Ako se ne navede razina kontrole


pristupa, podrazumijeva se
internal!

lanovi klasa (engl. members)


Varijable (engl. fields)
Svojstva (engl. properties)
Metode
Konstruktori

internal class Car


{
// tip dostupan samo unutar asemblija u
kojem
// je definiran
}
public class Car
{
// tip dostupan svima
}

Razvoj aplikacija u programskom jeziku C#

Klase
public class Car
{
public string Name;
public int FuelLeftMeterValue;
public SteeringWheel Wheel;
private FuelTank _tank;
private FuelInjectionPump _pump;
public void TurnOn()
{
BuildHeat();
InjectFuelIntoCylinders();
IncreaseCylinderPressure();
...
}
private void BuildHeat()
{
}
private void InjectFuelIntoCilinders()
{
}
...

Mogunost kontrole pristupa svim lanovima


klasa (varijablama, svojstvima, metodama,
konstruktorima...)
public
Svima dostupan pristup
private
Dostupno samo unutar klase u kojoj je definirano
internal
Dostupno samo unutar asemblija u kojem je
definirano
protected
Dostupno samo unutar klase i njenih izvedenih
klasa

Razvoj aplikacija u programskom jeziku C#

Properties
Ne preporua se drati varijable javno dostupne
Ne postoji kontrola nad pristupom varijabli
public class Car
{
public int TopSpeed;
}

Car mazda = new Car();


// Bre od brzine svjetlosti
mazda.TopSpeed = int.MaxValue;

10/31/16

Razvoj aplikacija u programskom jeziku C#

Properties
Rjeenje: definirati kontrolirani i javni
pristup varijablama kroz metode
Varijabla je privatna
Pristup kontroliran kroz javne get i set
metode
Car mazda = new Car();
mazda.SetTopSpeed(int.MaxValue);
// brzina svjetlosti
int topSpeed = mazda.GetTopSpeed();

public class Car


{
private int _topSpeed;
public int GetTopSpeed()
{
return _topSpeed;
}
public void SetTopSpeed(int value)
{
if (value >
PhsyicalConstants.SpeedOfLight)
{
value =
PhsyicalConstants.SpeedOfLight;
}
_topSpeed = value;
}
}

10/31/16

Razvoj aplikacija u programskom jeziku C#

Properties
C# rjeenje: definirati kontrolirani
i javni pristup varijablama kroz
svojstva (engl. property)
Kraa sintaksa od definiranja
metoda
Van klase, kontroliranom svojstvu
se pristupa kao i svakoj drugoj
varijabli - bolje!
Car mazda = new Car();
// Bre od brzine svjetlosti
mazda.TopSpeed = int.MaxValue;
int topSpeed = mazda.TopSpeed;

10/31/16

public class Car


{
private int _topSpeed;
public int TopSpeed
{
get
{
return _topSpeed;
}
set
{
if (value >
PhsyicalConstants.SpeedOfLight)
{
value =
PhsyicalConstants.SpeedOfLight;
}
_topSpeed = value;
}
}
}

Razvoj aplikacija u programskom jeziku C#

Properties
public class Car
{
private int _topSpeed;
public int GetTopSpeed()
{
return _topSpeed;
}

public void SetTopSpeed(int value)


{
if (value >
syicalConstants.SpeedOfLight)
{
value =
syicalConstants.SpeedOfLight;
}
_topSpeed = value;
}

Nije konvencija u C# programima

10/31/16

public class Car


{
private int _topSpeed;
public int TopSpeed
{
get
{
return _topSpeed;
}
set
{
if (value >
PhsyicalConstants.SpeedOfLight)
{
value =
PhsyicalConstants.SpeedOfLight;
}
_topSpeed = value;
}
}
Koristiti u C#
}
Razvoj aplikacija u programskom jeziku C#

Properties
public class Car
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}

public class Car


{
public string Name { get; set; }
}

Kraa sintaksa za jednostavne


getere i setere

10/31/16

Razvoj aplikacija u programskom jeziku C#

10

Properties
public class Car
{
public string Name;
}

Ne preporua se koristiti javne varijable


u C#
Moemo naknadno transformirati
javnu varijablu u svojstvo sa get i set
metodama, ali dolazi do promjene
API-ja. Promjenili smo vrstu lana
(field -> property) to moe utjecati
na kod koji ovisi o tome

10/31/16

public class Car


{
public string Name { get; set; }
}

Preporua se u C#
Moemo dodati get/set funkcionalnost
naknadno bez promjene API-a
Tehnologije nad .NET-om rade
uglavnom s Property lanovima

Razvoj aplikacija u programskom jeziku C#

11

Properties
public class Car
{
private string _name;
public string Name
{
get
{
return _name;
}
}

Read-only properties
Klasa interno postavlja vrijednost
_name varijable
Izvan klase, ime se moe samo
itati

10/31/16

Razvoj aplikacija u programskom jeziku C#

12

Konstruktori
Objekti imaju stanje koje moda elimo
postaviti prije nego to krenemo s uporabom
npr. Naziv, maksimalnu brzinu automobila...

Konstruktor je metoda koja se poziva nakon


to je objekt konstruiran na heapu
Konstruktor nema povratni tip (niti void)
Naziv konstruktor metode je uvijek identian klasi
koju konstruira
Konstruktor moe definirati ulazne argumente (kao
i svaka druga metoda)

10/31/16

Razvoj aplikacija u programskom jeziku C#

public class Car


{
public Car()
{
// Logika koja
// konstruira objekt
}
}

Car mazda = new Car();

13

Konstruktori
Svaka klasa moe definirati
proizvoljan broj razliitih konstruktora

public class Car


{
public string Name { get; set; }
public DateTime DateBuilt { get; set; }
public Car()
{
Name = "Defaultno ime";
DateBuilt = DateTime.Now;
}

Car mazda1 = new Car();


Car mazda2 = new Car("Mazda");
Car mazda3 = new Car("Mazda",
DateTime.Now);

public Car(string name)


{
Name = name;
DateBuilt = DateTime.Now;
}
public Car(string name, DateTime
dateBuilt)
{
Name = name;
DateBuilt = dateBuilt;
}
10/31/16

Razvoj aplikacija u programskom jeziku C#

14

Konstruktori
Ako nismo definirali niti jedan
konstruktor, implicitno se
podrazumijeva prazan konstruktor koji
ne prima nikakve parametre
Defaultni konstruktor se vie ne
podrazumijeva jednom kada postoji
eksplicitna definicija konstruktora

10/31/16

public class Car


{
public string Name { get; set; }
public DateTime DateBuilt { get; set; }
public Car(string name)
{
Name = name;
DateBuilt = DateTime.Now;
}
}

Car mazda1 = new Car();

Razvoj aplikacija u programskom jeziku C#

15

Sintaksa za inicijalizaciju objekta


Najee konstruktori nee pokriti
inicijalizaciju svih javnih svojstva i
varijabli
Sintaksa za inicijalizaciju objekata
omoguava nam da postavimo eljena
javna svojstva i varijable u jednom
koraku

Car mazda = new Car("Mazda")


{
Version = "323f",
DateBuilt = DateTime.Now
};

Ali nemojte zapostaviti konstruktore


Konstruktori mogu osigurati postavljena
javna svojstva, sintaksa za inicijalizaciju
je opcionalna.
10/31/16

Razvoj aplikacija u programskom jeziku C#

16

Kljuna rije - this


Unutar definicije klase
raspolaemo kljunom rijei
this

public class Car


{
public string Name { get; set; }
public DateTime DateBuilt { get; set; }
public Car(string name)
{
Name = name;
DateBuilt = DateTime.Now;
}

This predstavlja referencu na


konkretnu instancu klase
unutar opisa iste

public void PrintState()


{
Console.WriteLine("Car name is {0},
but it can also be accessed like {1},
Name, this.Name);
}

Car mazda = new


Car("Mazda");
mazda.PrintState();

10/31/16

Razvoj aplikacija u programskom jeziku C#

17

Kljuna rije - this


Kljunu rije this najee koristimo da bi
razluili vieznanost imena
Oba primjera se kompajliraju bez greke
U prvom primjeru smo vrijednost ulaznog
argumenta name spremili nazad u samog
sebe vjerojatno nam to nije bilo na umu

U drugom primjeru smo operatorom this


referencirali varijablu klase i nju postavili na
vrijednost ulaznog argumenta

10/31/16

Razvoj aplikacija u programskom jeziku C#

private string name;


public Car(string name)
{
name = name;
}

private string name;


public Car(string name)
{
this.name = name;
}

18

Temelji OOP-a
Tri temelja objektno orijentiranog programiranja
Enkapsulacija
Nasljeivanje
Polimorfizam

10/31/16

Razvoj aplikacija u programskom jeziku C#

19

Temelji OOP - Enkapsulacija


Do sad pokazani elementi grade jedan od temelja OOP-a Enkapsulaciju.
Enkapsulacija mogunost jezika da sakrijemo implementacijske detalje nekog
tipa od korisnika
npr. DatabaseObject s metodama OpenConnection() i CloseConnection()
Ne moramo se zamarati linijama koda koje stoje unutar te dvije operacije.
Napadamo problem s vie razine apstrakcije, kreiramo instancu DatabaseObject klase i
komuniciramo s bazom preko javnog suelja

Enkapsulacija osim apstrakcije nudi i zatitu integriteta podataka


Vanjski svijet upravlja stanjem u kontroliranim uvjetima (izbjegavati varijable s javnim
pristupom)
Javno deklarirane varijable potencijalno se mogu dovesti u koruptivno stanje
10/31/16

Razvoj aplikacija u programskom jeziku C#

20

Temelji OOP - Enkapsulacija


Dobro enkapsulirana klasa kontrolira pristup podacima i skriva detalje kako
operira od vanjskog svijeta black box programming
Vanjski sustav pristupa kroz javno suelje klase (javne metode i svojstva)
Moemo mijenjati unutarnju implementaciju funkcionalnosti bez da utjeemo na ostatak
sustava koji koristi klasu
Osim ako se ne javi potreba za promjenom javnog suelja

10/31/16

Razvoj aplikacija u programskom jeziku C#

21

Temelji OOP - Nasljeivanje


Nasljeivanje mogunost jezika da gradimo nove klase bazirane na drugim
klasama. Drugi temelj OOP-a.
npr. elimo definirati klasu Cabriolet (auto sa sklopivim krovom)
Kabriolet je auto (relacija is-a) te treba sadravati sva svojstva i funkcionalnost auta (pali, gasi,
trenutna brzina, maksimalna brzina...), ali proiruje priu sa sklopivim krovom
Is-a relacija moe se opisati kroz C# sintaksu tzv. classical inheritance (colon operator)
public class Cabriolet : Car
{
// ...
}

10/31/16

Car - bazna klasa, klasa roditelj...


Cabriolet izvedena klasa, dijete klasa...

Razvoj aplikacija u programskom jeziku C#

22

Temelji OOP - Nasljeivanje

public class Cabriolet : Car


{
public bool IsRoofOpen { get;
et; }
public void ToogleRoofOpen()
{
IsRoofOpen = !IsRoofOpen;
}
}
Cabriolet cabriolet = new Cabriolet();
cabriolet.Name = "Mazda";
cabriolet.Version = "MX-5";
cabriolet.ToogleRoofOpen();
cabriolet.TurnOn();

10/31/16

Izvedena klasa Cabriolet


nasljedila je sve lanove svog
roditelja Car (osim
konstruktora)
Izvedena klasa proirila je
funkcionalnost obinog auta
svojstvo IsRoofOpen
metoda ToggleRoofOpen()

Razvoj aplikacija u programskom jeziku C#

23

Temelji OOP - Nasljeivanje

public class A
{
public string Name { get; set; }
protected string ProtectedName { get;
set; }
internal string InternalName { get; set;
}
private string PrivateName { get; set; }
}

Unutar izvedene klase moemo


pristupati samo public i protected
lanovima klase roditelja
Internal lanovi dostupni su ako je
izvedena klasa definirana u istom
asembliju
Private lanovi nisu dostupni

public class B : A
{
public void AccessTest()
{
Name = "This works";
ProtectedName = "This also works";
InternalName = "This works.. if I'm
in
the same assembly";
PrivateName = "Compiler error!";
}
}
Razvoj aplikacija u programskom jeziku C#
10/31/16

24

Temelji OOP - Nasljeivanje


public class A
{
public A(int x, int y)
{

Izvedena klasa ne nasljeuje


konstruktore, ali moe ih pozivati s
kljunom rijei base
U sluaju da roditelj klasa nema
definiran prazan konstruktor (kao na
primjeru), duni smo ga pozvati u
izvedenoj klasi (u svakom
definiranom konstruktoru)

}
}
public class B : A
{
public B() : base(0, 0)
{
}
public B(int x, int y) : base(x, y)
{
}
}
10/31/16

Razvoj aplikacija u programskom jeziku C#

25

Temelji OOP - Nasljeivanje


public class A
{
public A(int x, int y)
{

Izvedena klasa ne nasljeuje


konstruktore, ali moe ih pozivati s
kljunom rijei base
U sluaju da roditelj klasa nema
definiran prazan konstruktor (kao na
primjeru), duni smo ga pozvati u
izvedenoj klasi (u svakom
definiranom konstruktoru)

}
}
public class B : A
{
public B() // compiler error
{
}
public B(int x, int y) : base(x, y)
{
}
}
10/31/16

Razvoj aplikacija u programskom jeziku C#

26

Temelji OOP - Nasljeivanje


public class A
{
public A(int x, int y)
{
}
}
public class B : A
{
// compiler error
}

10/31/16

Izvedena klasa ne nasljeuje


konstruktore, ali moe ih pozivati s
kljunom rijei base
U sluaju da roditelj klasa nema
definiran prazan konstruktor (kao na
primjeru), duni smo ga pozvati u
izvedenoj klasi (u svakom
definiranom konstruktoru)

Razvoj aplikacija u programskom jeziku C#

27

Temelji OOP - Nasljeivanje


Kljunom rijei sealed moemo
sprijeiti nasljeivanje odreene
klase
Odluka kod dizajna
npr. odluili smo da nema smisla
nasljeivati dalje Cabriolet klasu
Ima smisla kod nekakvih Utility
klasa
System namespace pun je sealed
klasa (npr. String!)

10/31/16

public sealed class Cabriolet : Car


{
}
// Compiler error
public class CabrioletWannabe :
Cabriolet
{
}

Razvoj aplikacija u programskom jeziku C#

28

Temelji OOP - Nasljeivanje


public class A
{
}
public class B
{
}
// compiler error
public class C : A, B
{

Klase u C# mogu imati samo jednu baznu


klasu
Nije mogue napraviti tipove koji nasljeuju
od vie razliitih klasa (kao u C++)
Razlog: tako je po dizajnu. MI (multiple
inheritance) unosi veliku kompleksnost u
jezik, a nosi premalo benefita

10/31/16

Razvoj aplikacija u programskom jeziku C#

29

Temelji OOP - Polimorfizam


Trei temelj OOP-a Polimorfizam (po naem vieoblije)
Dva su aspekta polimorfizma
Dinamiki polimorfizam oblik se razluuje za vrijeme izvoenja
Izvedene klase moemo tretirati kao objekte bazne klase
Izvedene klase mogu definirati svoje vlastite verzije metoda ili lanova koje je ve definirala
bazna klasa (engl. method overriding)

Statiki polimorfizam oblik se razluuje za vrijeme kompajliranja


Metode mogu doi u vie oblika, a koju e koristiti u odreenoj situaciji odreuje kompajler
za vrijeme kompajliranja (engl. method overloading)

10/31/16

Razvoj aplikacija u programskom jeziku C#

30

Temelji OOP - Polimorfizam


Statiki polimorfizam methods overloading
Mogunost definiranja vie istoimenih metoda, ali sa drugim ulaznim argumentima
S ovim smo se ve upoznali kod primjera s konstruktorima!

Koja e se metoda koristiti u odreenom scenariju razluuje se za vrijeme kompajliranja


public class Adder
{
public void Add(string a1, string

2)

Add(5, 5);
Add("Hello", "World");

{
Console.WriteLine(a1 + a2);
}
public void Add(int a1, int a2)
{
Console.WriteLine(a1 + a2);
}
}
10/31/16

Razvoj aplikacija u programskom jeziku C#

31

Temelji OOP - Polimorfizam


Dinamiki polimorfizam dolazi u dva okusa
1. Izvedene klase mogu doi u obliku svoje bazne klase
Car cabriolet = new Cabriolet();
cabriolet.ToggleRoofOpen(); // compiler error
Car regularCar = new Car();
bool
bool
bool
bool

b1
b2
b3
b4

=
=
=
=

cabriolet is Cabriolet; // true


cabriolet is Car; // true
regularCar is Cabriolet; // false
regularCar is Car; // true

void SellCar(Car car)


{
// sell
}

Cabriolet cabriolet = new Cabriolet


SellCar(cabriolet);
Car regularCar = new Car();
SellCar(regularCar);

Cabriolet x = cabriolet as Cabriolet; // okay


Cabriolet y = regularCar as Cabriolet; // null
Cabriolet z = (Cabriolet)cabriolet; // okay
Cabriolet w = (Cabriolet)regularCar; // rui aplikaciju
10/31/16

Razvoj aplikacija u programskom jeziku C#

32

Temelji OOP - Polimorfizam


Dinamiki polimorfizam dolazi u dva okusa
1. Izvedene klase mogu doi u obliku svoje bazne klase

10/31/16

Razvoj aplikacija u programskom jeziku C#

33

Temelji OOP - Polimorfizam


Dinamiki polimorfizam dolazi u dva okusa
2. Izvedene klase mogu ponuditi alternativnu implementaciju bazne metode

10/31/16

Razvoj aplikacija u programskom jeziku C#

34

Temelji OOP - Polimorfizam


Dinamiki polimorfizam dolazi u dva okusa
2. Izvedene klase mogu ponuditi alternativnu implementaciju bazne metode

public class Animal


{
public void Sound()
{
Console.WriteLine("Animal
nd?");
}
}
public class Dog : Animal
{
public void Sound()
{
Console.WriteLine(Wuf");
}
}

10/31/16

Animal animal1 = new Dog();


animal1.Sound();
Animal animal2 = new Animal();
animal2.Sound();
Dog directDog = new Dog();
animal3.Sound();

Output
Animal sound?
Animal sound?
Wuf
Nismo dobili eljeno ponaanje!
Razvoj aplikacija u programskom jeziku C#

35

Temelji OOP - Polimorfizam


Dinamiki polimorfizam dolazi u dva okusa
2. Izvedene klase mogu ponuditi alternativnu implementaciju bazne metode

public class Animal


{
public virtual void Sound()
{
Console.WriteLine("Animal
nd?");
}
}
public class Dog : Animal
{
public override void Sound()
{
Console.WriteLine(Wuf");
}
}

10/31/16

Animal animal1 = new Dog();


animal1.Sound();
Animal animal2 = new Animal();
animal2.Sound();

Output
Wuf
Animal sound?

Razvoj aplikacija u programskom jeziku C#

36

Temelji OOP - Polimorfizam


Dinamiki polimorfizam dolazi u dva okusa
2. Izvedene klase mogu ponuditi alternativnu implementaciju bazne metode

public class Animal


{
public void Sound()
{
Console.WriteLine("Animal
nd?");
}
}
public class Dog : Animal
{
public override void Sound() // compiler

or
{
Console.WriteLine(Wuf");
}
}
10/31/16

Razvoj aplikacija u programskom jeziku C#

37

Apstraktne klase
public abstract class Animal
{
public DateTime DateBorn { get; set;
public string Name { get; set; }
public void Move()
{
Console.WriteLine("Moving...");
}
public abstract void Sound();
}
public class Dog : Animal
{
public override void Sound()
{
Console.WriteLine("Wuf Wuf");
}
}

10/31/16

Apstraktne klase
Klase koje predstavljaju apstraktne tipove
apstraktni tipovi ne mogu se instancirati
Smisao apstraktnih klasa je da postave
temelje za budue izvedene klase
Mogue oznaiti lanove s kljunom rijei

abstract
Implementacija e se zahtijevati od
izvedenih klasa
Implementaciju izostavljamo u
apstraktnoj klasi (apstraktna je, vezana
za konkretnu izvedenu klasu)

Razvoj aplikacija u programskom jeziku C#

38

Apstraktne klase
public abstract class Animal
{
public DateTime DateBorn { get; set;
public string Name { get; set; }
public void Move()
{
Console.WriteLine("Moving...");
}
public abstract void Sound();
}
public class Dog : Animal // compiler

or
{
}

10/31/16

Apstraktne klase
Klase koje predstavljaju apstraktne tipove
apstraktni tipovi ne mogu se instancirati
Smisao apstraktnih klasa je da postave
temelje za budue izvedene klase
Mogue oznaiti lanove s kljunom rijei

abstract
Implementacija e se zahtijevati od
izvedenih klasa
Implementaciju izostavljamo u
apstraktnoj klasi (apstraktna je, vezana
za konkretnu izvedenu klasu)

Razvoj aplikacija u programskom jeziku C#

39

Apstraktne klase
Apstraktne klase

Animal dogAnimal = new Dog(); //okay


Animal animalDirectly = new Animal(); // compiler
error

Klase koje predstavljaju apstraktne tipove


apstraktni tipovi ne mogu se instancirati
Smisao apstraktnih klasa je da postave
temelje za budue izvedene klase
Mogue oznaiti lanove s kljunom rijei

abstract
Implementacija e se zahtijevati od
izvedenih klasa
Implementaciju izostavljamo u
apstraktnoj klasi (apstraktna je, vezana
za konkretnu izvedenu klasu)

10/31/16

Razvoj aplikacija u programskom jeziku C#

40

Interfaces
Suelja (engl. Interfaces) omoguuju nam opisivanje suelja klasa
Suelje klase javna svojstva i metode
Klasa ako implementira suelje, duna je imati navedene javne lanove
public interface IPipeFixer
{
Wrench Wrench { get; }
void FixPipe();
}

public interface IChangeBikeTires


{
void ChangeTire(Bike bike);
}

10/31/16

public class Mechanic : IChangeBikeTires, IPipeFixer


{
// IPipeFixer dio
public Wrench Wrench { get; }
public void FixPipe()
{
}
// IChangeBikeTires dio
public void ChangeTire(Bike bike)
{
}
}

Razvoj aplikacija u programskom jeziku C#

41

Interfaces

class LadyInDistress
{
public Bike Bike { get; set; }
void FixMyBikeTire(Mechanic
anic)
{
mechanic.ChangeTire(Bike);
}
}

Program to interface, not implementation

class LadyInDistress
{
public Bike Bike { get; set; }
void FixMyBikeTire(IChangeBikeTires anyone)
{
anyone.ChangeTire(Bike);
}
}

10/31/16

public class Mechanic : IChangeBikeTires, IPipeF


{
// IPipeFixer dio
public Wrench Wrench { get; }
public void FixPipe()
{
}
// IChangeBikeTires dio
public void ChangeTire(Bike bike)
{
}
}
public class Me : IChangeBikeTires
{
public void ChangeTire(Bike bike)
{
}
}

Razvoj aplikacija u programskom jeziku C#

42

Interfaces
public interface IDatabase
{
Product[] GetProducts();
Category[] GetCategories();
void AddProduct();
void DeleteProduct();
...
}

public class TextFileDummyDevelopmentDatabase :


IDatabase
{
public Product[] GetProducts()
{
}
public Category[] GetCategories()
{
}
public void AddProduct()
{
}
public void DeleteProduct()
{
}
}

10/31/16

Razvoj aplikacija u programskom jeziku C#

43

Interfaces
public interface IDatabase
{
Product[] GetProducts();
Category[] GetCategories();
void AddProduct();
void DeleteProduct();
...
}

public class SQLDatabase : IDatabase


{
public Product[] GetProducts()
{
}
public Category[] GetCategories()
{
}
public void AddProduct()
{
}
public void DeleteProduct()
{
}
}

10/31/16

Razvoj aplikacija u programskom jeziku C#

44

You might also like