310 likes | 472 Views
Pristup podacima članovima. Podaci članovi treba da budu sakriveni, tj. da imaju private ili protected pristup u saglasnosti sa principom enkapsulacije – sakrivanja podataka i metoda koje se ne moraju izložiti korisniku klase Jedan od načina za pristup privatnim podacima je preko javnih metoda
E N D
Pristuppodacimačlanovima • Podaci članovi treba da budu sakriveni, tj. da imaju private ili protected pristup u saglasnosti sa principom enkapsulacije – sakrivanja podataka i metoda koje se ne moraju izložiti korisniku klase • Jedan od načina za pristup privatnim podacima je preko javnih metoda • Dakle, za pristup privatnim podacima je neophodno da se pozivaju javne – public procedure • Pristup privatnim podacima preko javnih procedura nije elegantan – treba pozivati procedure • U C#-u postoji i drugi mehanizam za pristup privatnim podacima preko specijalnih pristupnih metoda get i set
Javni podaci • structScreenPosition • { • public ScreenPosition(int x, int y) • { • this.X = rangeCheckedX(x); • this.Y = rangeCheckedY(y); • } • public int X; • public int Y; • private static intrangeCheckedX(int x) • { • if (x < 0 || x > 1280) • { • throw new ArgumentOutOfRangeException(“X”); • } • return x; • } • private static intrangeCheckedY(int y) • { • if (y < 0 || y > 1024) • { • throw new ArgumentOutOfRangeException(“Y”); • } • return y; • } • }
Pristup javnim podacima • ScreenPosition origin = new ScreenPosition(0, 0); • ... • int xpos = origin.X; • origin.Y = -100; // oops
Privatni podaci • structScreenPosition • { • ... • public intGetX() • { • return this.x; • } • public void SetX(intnewX) • { • this.x = rangeCheckedX(newX); • } • ... • private static intrangeCheckedX(int x) { ... } • private static intrangeCheckedY(int y) { ... } • private int x, y; • }
Pristup privatnim podacima • int xpos = origin.GetX(); • origin.SetX(xpos + 10); • Ekvivalentan pristup preko javnih promenljivih: • origin.X += 10; • Svojstva – properties spajaju dobra svojstva pristupa privatnim podacima preko javnih procedura sa jednostavnošću pristupa preko javnih promenljivih
Properties - svojstva • AccessModifier Type PropertyName • { • get • { • // read accessor code • } • set • { • // write accessor code • } • }
struct ScreenPosition • { • public ScreenPosition(int X, int Y) • { • this.x = rangeCheckedX(X); • this.y = rangeCheckedY(Y); • } • public int X • { • get { return this.x; } • set { this.x = rangeCheckedX(value); } • }
public int Y • { • get { return this.y; } • set { this.y = rangeCheckedY(value); } • } • private static int rangeCheckedX(int x) { ... } • private static int rangeCheckedY(int y) { ... } • private int x, y; • } • Set accessor – pristupni metod za zadavanje vrednosti koristi skriveni – ugradjeni parametar value
Korišćenje svojstava • ScreenPosition origin = new ScreenPosition(0, 0); • int xpos = origin.X; // calls origin.X.get • int ypos = origin.Y; // calls origin.Y.get • origin.X = 40; // calls origin.X.set, with value set to 40 • origin.Y = 100; // calls origin.Y.Set, with value set to 100 • origin.X += 10;
Read-Only Properties • struct ScreenPosition • { • ... • public int X • { • get { return this.x; } • } • } • origin.X = 140; // compile-time error
Write-Only Properties struct ScreenPosition { ... public int X { set { this.x = rangeCheckedX(value); } } } Console.WriteLine(origin.X); // compile-time error origin.X = 200; // compiles OK origin.X += 10; // compile-time error
Tip pristupa svojstvima • struct ScreenPosition • { • ... • public int X • { • get { return this.x; } • private set { this.x = rangeCheckedX(value); } • } • public int Y • { • get { return this.y; } • private set { this.y = rangeCheckedY(value); } • } • ... • private int x, y; • }
Neka ograničenja svojstava • Može se promenit svojstvo pristupa samo jedne metode – set ili get a ne obe, jer to onda gubi smisao • Promenjeno svojstvo može biti samo više restriktivno u odnosu na podešavanje na višem nivou • ScreenPosition location; • location.X = 40; // compile-time error, location not assigned • MyMethod(ref location.X); // compile-time error • Get i set metodi ne mogu imati parametre • const int X { get { ... } set { ... } } // compile-time error
Greška sa beskonačnim cirkularnim pozivima • class Employee • { • private int employeeID; • public int EmployeeID; • { • get { return this.EmployeeID; } • set { this.EmployeeID = value; } • }
Ne Adekvatno korišćenje svojstava • class BankAccount • { • ... • public money Balance • { • get { ... } • set { ... } • } • private money balance; • }
Adekvatno korišćenje svojstava • class BankAccount • { • ... • public money Balance { get { ... } } • public void Deposit(money amount) { ... } • public bool Withdraw(money amount) { ... } • private money balance; • }
Interface-i i svojstva • interface IScreenPosition • { • int X { get; set; } • int Y { get; set; } • } • Svaka klasa ili struktura koja implementira interface IScreenPosition mora da ima svojstva X i Y sa get i set metodama pristupa
struct ScreenPosition : IScreenPosition • { • ... • public int X • { • get { ... } • set { ... } • } • public int Y • { • get { ... } • set { ... } • } • ... • }
class ScreenPosition : IScreenPosition • { • ... • public virtual int X • { • get { ... } • set { ... } • } • public virtual int Y • { • get { ... } • set { ... } • } • ... • }
struct ScreenPosition : IScreenPosition • { • ... • int IScreenPosition.X • { • get { ... } • set { ... } • } • int IScreenPosition.Y • { • get { ... } • set { ... } • } • ... • private int x, y; • }
Automatsko generisanje get i set metoda pristupa • class Circle • { • public int Radius{ get; set; } • ... • }
Kod sa prethodne strane se zamenjuje ekvivalentnim kodom class Circle { private int _radius; public int Radius { get { return this._radius; } set { this._radius = value; } } ... }
Inicijalizacija objekata pomoću svojstava • Inicijalizacija objekata se vrši u konstruktoru • Različite inicijalizacije se vrše sa različitim konstruktorima • Default konstruktor inicijalizuje objekat na podrazumevane vrednosti podataka članova • Ostali konstruktori vrše druge različite inicijalizacije • Ponekad može da nastane problem kada se želi inicijalizacija istog broja različitih podataka istog tipa, jer će u tom slučaju potpisi različitih konstruktora biti isti
Inicijalizacija klase trougla public class Triangle { private int side1Length; private int side2Length; private int side3Length; // default constructor - default values for all sides public Triangle() { this.side1Length = this.side2Length = this.side3Length = 10; }
// specify length for side1Length, default values for the others public Triangle(int length1) { this.side1Length = length1; this.side2Length = this.side3Length = 10; } // specify length for side1Length and side2Length, // default value for side3Length public Triangle(int length1, int length2) { this.side1Length = length1; this.side2Length = length2; this.side3Length = 10; }
public class Triangle { private int side1Length = 10; private int side2Length = 10; private int side3Length = 10; public int Side1Length { set { this.side1Length = value; } } public int Side2Length { set { this.side2Length = value; } } public int Side3Length { set { this.side3Length = value; } } }
Inicijalizacija objekata preko svojstava • Triangle tri1 = new Triangle { Side3Length = 15 }; • Triangle tri2 = new Triangle { Side1Length = 15, Side3Length = 20 }; • Triangle tri3 = new Triangle { Side2Length = 12, Side3Length = 17 }; • Triangle tri4 = new Triangle { Side1Length = 9, Side2Length = 12, Side3Length = 15 }; • Triangle tri5 = new Triangle(“Equilateral triangle”) { Side1Length = 3, Side2Length = 3, Side3Length = 3 };