Php magic get metodai. Getteriai ir seteriai – magija, kuri turi žinoti savo vietą

Norėdami valdyti, kaip naudojami laukai, galite sukurti gauti metodus ir nustatyti bei paviešinti juos. Jie suteikia galimybę kontroliuoti prieigą prie lauko. Tuo pačiu metu Amžiaus lauką geriau padaryti privatų, kad jo nebūtų galima tiesiogiai pasiekti už klasės ribų.

viešosios klasės sąskaita

privatus int amžius;

viešas int GetAge()

grąžinti šį.amžius;

public void SetAge (ant amžiaus)

if ((inAge > 0) && (inAge< 120))

this.age = inAge;

Dabar galime kontroliuoti prieigą prie savo lauko, tačiau tam reikia parašyti daug papildomo kodo. Norėdami pasiekti amžiaus vertę, turite iškviesti sukurtus metodus:

Paskyra s = new Account();

Console.WriteLine("Amžius: " + s.GetAge());

    1. Savybių naudojimas

Savybės palengvina duomenų valdymą. Amžiaus turtą galima deklaruoti taip:

viešosios klasės sąskaita

private int ageValue;

if ((reikšmė > 0) && (reikšmė< 120))

ageValue = vertė;

grąžinti amžiausValue;

Čia amžiaus vertė yra nuosavybė. Turtas deklaruoja skyrius, skirtas rašyti ir skaityti jo vertę. Šiuose skyriuose aprašyti veiksmai yra lygiaverčiai anksčiau aprašytiems metodams. Šiuo atveju savybės naudojamos taip pat, kaip ir įprasti laukai:

Paskyra s = new Account();

Console.WriteLine("Amžius: " + s.Amžius);

Kai ypatybė Amžius nustatoma į reikšmę, iškviečiamas nustatyto skyriaus kodas. Reikšmės raktinis žodis nurodo ypatybei priskirtą vertę. Skaitant Age nuosavybės vertę, iškviečiamas get sekcijos kodas. Šis metodas sujungia metodų naudojimo pranašumus ir leidžia dirbti su savybėmis taip pat lengvai, kaip ir su klasės laukais.

Savybių duomenų teisingumo tikrinimas . Jei bandysite nustatyti netinkamą amžiaus reikšmę (pvz., 150), aukščiau pateiktas kodas atliks galiojimo patikrinimą ir atmes reikšmę (niekas vyresnis nei 120 metų negali turėti sąskaitos mūsų banke), palikdamas senatvės reikšmę. Vienintelis būdas sužinoti, ar nuosavybei buvo priskirta vertė, yra patikrinti nuosavybės vertę po šios operacijos:

Paskyra s = new Account();

int newAge = 150;

if (s.Age != newAge)

Console.WriteLine("Amžiaus reikšmė nenustatyta");

Šiuo kodu bandoma nustatyti netinkamą 150 amžių, tada patikrinama, ar ta vertė buvo nustatyta. Jei reikšmei priskirti buvo naudojamas Set metodas, jis galėtų grąžinti vertę klaidinga Jei tai nepavyksta, naudojant nuosavybę vartotojas turi atlikti šiek tiek daugiau papildomo darbo.

Įvairūs nuosavybės vertės skaitymo būdai. Savybės leidžia atlikti kitus naudingus veiksmus.

viešas int AmžiusMėnesiais

grąžinti šį.ageValue * 12;

Nauja AgeInMonths nuosavybė aprašyta čia. Jis yra tik skaitomas, nes jame nėra nustatyto skyriaus. Ji grąžina amžiaus vertę mėnesiais, naudodama tą pačią vertę kaip ir amžiaus ypatybė. Tai reiškia, kad galite naudoti kelis įvairiais būdais gauti tą pačią vertę. Galima sukurti tik skaitymo ypatybes be galimybės jų tiesiogiai keisti, taip pat tik rašymo savybes, nors pastarosios naudojamos retai.

Vaizdinių elementų savybės . Tikslinga naudoti ypatybes banko sąskaitos aprašyme, kur reikia apsaugoti objektų duomenis. Tačiau „Silverlight“ į „TextBlock“ elementą galite įvesti bet kokį tekstą ir atrodo, kad nereikia tikrinti įvestos reikšmės galiojimo. Vykdant šį kodą sulėtės vertės įvedimo procesas. Taigi, jei teksto reikšmė būtų vieša, programoje būtų mažiau kodo ir ji veiktų greičiau.

Tačiau kai keičiame tekstą elemente TextBlock, norime, kad tekstas Silverlight puslapyje taip pat pasikeistų, pavyzdžiui, kai programa Adder rodo rezultatą. Jei programa tiesiog pakeistų lauko reikšmę, „Silverlight“ negalėtų žinoti, kad reikia atnaujinti pranešimą ekrane.

Tačiau jei tekstas yra ypatybė, kai atnaujinama elemento TextBlock reikšmė, bus paleistas atitinkamas metodas, kuris gali atnaujinti išsaugotą teksto laukelio reikšmę ir iškviesti metodą atnaujinti ekraną, kad būtų rodoma nauja reikšmė. Savybės suteikia galimybę manipuliuoti objektu, kai keičiasi jo vertė. Paprasta operacija:

resultTextBlock.Text = "0";

gali sukelti kelis šimtus C# operacijų, nes naujos reikšmės išsaugojimas elemente TextBlock suaktyvina ekrano vaizdo atnaujinimo operacijas.

Paskutinis atnaujinimas: 2018-07-29

Be įprastų metodų, C# kalba suteikia specialių prieigos metodų, vadinamų savybėmis. Jie leidžia lengvai pasiekti klasės laukus, sužinoti jų vertę arba juos nustatyti.

Standartinis nuosavybės aprašymas turi tokią sintaksę:

[access_modifier] return_type custom_name ( // nuosavybės kodas )

Pavyzdžiui:

Klasės asmuo (privatus eilutės pavadinimas; viešoji eilutės pavadinimas (gauti (grąžinti pavadinimą; ) nustatyti (vardas = vertė; ) ) )

Čia turime privataus vardo lauką ir viešą Vardo nuosavybę. Nors jie turi beveik tą patį pavadinimą, išskyrus registrą, tai yra ne kas kita, kaip stilius; jų pavadinimai gali būti savavališki ir nebūtinai turi sutapti.

Per šią nuosavybę galime valdyti prieigą prie vardo kintamojo. Standartiniame nuosavybės apibrėžime yra gauti ir nustatyti blokai. Gauti bloke grąžiname lauko reikšmę, o rinkinio bloke nustatome. Vertės parametras nurodo reikšmę, kurią reikia perduoti.

Šią nuosavybę galime naudoti taip:

Asmuo p = naujas Asmuo(); // Nustatyti ypatybę – suveikia Set blokas // reikšmė "Tom" yra ypatybei perduota reikšmė p.Name = "Tom"; // Gaukite ypatybės reikšmę ir priskirkite ją kintamajam – suaktyvinamas blokas Get string personName = p.Name;

Galbūt gali kilti klausimas, kam mums reikalingos savybės, jei šioje situacijoje galime apsieiti su paprastais klasės laukais? Tačiau savybės leidžia pridėti papildomos logikos, kurios gali prireikti, pavyzdžiui, priskiriant vertę klasės kintamajam. Pavyzdžiui, turime nustatyti amžiaus patikrą:

Klasė Asmuo ( privatus int age; public int Amžius ( set ( if (value< 18) { Console.WriteLine("Возраст должен быть больше 17"); } else { age = value; } } get { return age; } } }

Nustatyti ir gauti blokai neturi būti nuosavybėje tuo pačiu metu. Jei ypatybę apibrėžia tik get blokas, tai ypatybė yra tik skaitoma – galime gauti jos vertę, bet nenustatyti. Ir atvirkščiai, jei nuosavybėje yra tik nustatytas blokas, tada tą ypatybę galima tik įrašyti – galite nustatyti tik reikšmę, bet jos gauti negalite:

Klasės asmuo (privačios eilutės pavadinimas; // tik skaitoma nuosavybė viešosios eilutės pavadinimas ( get ( return name; ) ) private int age; // tik rašoma nuosavybė public int Amžius ( rinkinys ( amžius = vertė; ) ) )

Prieigos modifikatoriai

Galime pritaikyti prieigos modifikatorius ne tik visam turtui, bet ir atskiriems blokams – gauti arba nustatyti:

Klasės asmuo (privatus eilutės pavadinimas; viešoji eilutė Vardas ( gauti ( grąžinti pavadinimą; ) privatus rinkinys ( vardas = vertė; ) ) viešasis asmuo (eilutės pavadinimas, int amžius) ( Vardas = vardas; Amžius = amžius; ) )

Dabar uždarojo rinkinio bloką galime naudoti tik šioje klasėje – jo metoduose, savybėse, konstruktoriuje, bet ne kitoje klasėje:

Asmuo p = naujas Asmuo("Tomas", 24); // Klaida – rinkinys deklaruojamas privačiu modifikatoriumi //p.Name = "Jonas"; Console.WriteLine(p.Vardas);

Naudojant savybių modifikatorius, reikia atsižvelgti į keletą apribojimų:

    Galima nustatyti rinkinio arba gauti bloko modifikatorių, jei ypatybė turi ir set, ir get blokus.

    Tik vienas rinkinys arba gavimo blokas gali turėti prieigos modifikatorių, bet ne abu

    Nustatyti arba gauti bloko prieigos modifikatorius turi būti labiau ribojantis nei nuosavybės prieigos modifikatorius. Pavyzdžiui, jei nuosavybės modifikatorius yra viešas, bloke set/get gali būti apsaugoti tik modifikatoriai: vidinis, vidinis, apsaugotas, privatus.

Inkapsuliavimas

Aukščiau matėme, kad prieiga prie privačios klasės kintamųjų nustatoma per ypatybes. Klasės būsenos slėpimas nuo išorinių trukdžių tokiu būdu parodo inkapsuliavimo mechanizmą, kuris yra viena iš pagrindinių objektinio programavimo sąvokų. (Verta pažymėti, kad pati inkapsuliavimo sąvoka turi nemažai skirtingų interpretacijų, kurios ne visada sutampa viena su kita) Privačios prieigos modifikatorių naudojimas apsaugo kintamąjį nuo išorinės prieigos. Norėdami valdyti prieigą, daugelis programavimo kalbų naudoja specialius metodus, geterius ir seterius. C# kalboje jų vaidmenį dažniausiai atlieka savybės.

Pavyzdžiui, yra tam tikra sąskaitos klasė, kurioje yra sumos laukas, nurodantis sumą:

Klasės sąskaita (vieša tarpinė suma;)

Kadangi sumos kintamasis yra viešas, galime jį pasiekti bet kurioje programos vietoje ir jį pakeisti, įskaitant bet kokios netinkamos reikšmės nustatymą, pavyzdžiui, neigiamą. Mažai tikėtina, kad toks elgesys yra pageidautinas. Todėl inkapsuliavimas naudojamas apriboti prieigą prie sumos kintamojo ir paslėpti jį klasėje:

Klasės sąskaita ( privati ​​int suma; viešoji int suma ( gauti (grąžinimo suma;) nustatyta ( if (reikšmė > 0) ( suma=vertė; ) ) ) )

Automatinės savybės

Savybės valdo prieigą prie klasės laukų. Tačiau ką daryti, jei turime keliolika ar daugiau laukų, tada apibrėžti kiekvieną lauką ir parašyti to paties tipo savybę būtų varginantis. Todėl į .NET sistemą buvo įtrauktos automatinės savybės. Jie turi sutrumpintą deklaraciją:

Klasės Asmuo (vieša eilutė Vardas ( gauti; nustatyti; ) public int Amžius ( gauti; nustatyti; ) viešasis asmuo (eilutės pavadinimas, int amžius) ( Vardas = vardas; Amžius = amžius; ) )

Tiesą sakant, čia irgi kuriami laukai ypatybėms, tik juos kode nesukuria programuotojas, o kompiliatorius automatiškai juos sugeneruoja kompiliavimo metu.

Koks yra automatinių savybių pranašumas, jei iš esmės jie tiesiog pasiekia automatiškai sukurtą kintamąjį, kodėl gi ne tiesiogiai pasiekti kintamąjį be automatinių savybių? Faktas yra tas, kad bet kuriuo metu, jei reikia, galime išplėsti automatinę nuosavybę į įprastą nuosavybę ir pridėti tam tikrą logiką.

Verta manyti, kad negalite sukurti automatinio tik rašymo ypatybių, kaip tai daroma standartinių savybių atveju.

Automatinėms ypatybėms galima priskirti numatytąsias reikšmes (automatinių savybių inicijavimas):

Klasė Asmuo ( vieša eilutė Vardas ( get; set; ) = "Tomas"; public int Amžius ( get; set; ) = 23; ) klasė Programa ( statinė negalioja Pagrindinis (string args) ( Asmens asmuo = naujas asmuo (); konsolė .WriteLine(person.Name); // Tom Console.WriteLine(person.Age); // 23 Console.Read(); ) )

Ir jei nenurodysime asmens objekto Vardo ir Amžiaus savybių reikšmių, bus taikomos numatytosios reikšmės.

Automatinės savybės taip pat gali turėti prieigos modifikatorius:

Klasės asmuo (vieša eilutė Vardas (privatus rinkinys; gauti;) viešas asmuo (eilutė n) (Vardas = n; ) )

Galime pašalinti nustatytą bloką ir padaryti automatinę ypatybę tik skaitymą. Šiuo atveju, norint išsaugoti šios ypatybės reikšmę, jai bus netiesiogiai sukurtas laukas su tik skaitymo modifikatoriumi, todėl reikia atsižvelgti į tai, kad tokias get-ypatybes galima nustatyti arba iš klasės konstruktoriaus, kaip pavyzdyje. aukščiau arba inicijuojant nuosavybę:

Klasės asmuo (vieša eilutė Vardas ( get;) = "Tomas")

Trumpasis ypatybių žymėjimas

Kaip ir metodai, galime sutrumpinti savybes. Pavyzdžiui:

Klasės asmuo (privatus eilutės pavadinimas; // atitinka viešą eilutę Vardas ( gauti ( grąžinti pavadinimą; ) ) vieša eilutė Vardas => vardas; )

Sąsajos įgyvendinimas Nustatyti yra netvarkingas rinkinys, kuriame negali būti pasikartojančių duomenų.

Sąsaja Nustatyti apima šiuos metodus:

Metodasapibūdinimas
pridėti (O objektas) Elemento įtraukimas į kolekciją, jei jo trūksta. Grąžina true, jei elementas buvo pridėtas.
pridėti viską (rinkinys c) Kolekcijos elementų pridėjimas, jei jų trūksta.
aišku () Kolekcijos išvalymas.
yra (O objektas) Elemento buvimo rinkinyje patikrinimas. Grąžina tiesa, jei elementas rastas.
yra viskas (rinkinys c) Kolekcijos buvimo rinkinyje patikrinimas. Grąžina tiesa, jei rinkinyje yra visi elementai.
lygus (O objektas) Lygybės patikrinimas.
maišos kodas () Rinkinio maišos kodo gavimas.
Yra tuščias() Elementų buvimo patikrinimas. Grąžina tiesa, jei kolekcijoje nėra elementų.
iteratorius () Funkcija gauti kolekcijos iteratorių.
pašalinti (O objektas) Elemento pašalinimas iš rinkinio.
pašalinti viską (rinkinys c) Iš rinkinio pašalinami visi perduotos kolekcijos elementai.
išlaikyti viską (rinkinys c) Elementų, kurie nepriklauso perduotai kolekcijai, pašalinimas.
dydis () Kolekcijos elementų skaičius
toArray () Aibės konvertavimas į elementų masyvą.
tomasyvas(T a) Aibės konvertavimas į elementų masyvą. Skirtingai nuo ankstesnio metodo, kuris grąžina objektų tipo objektų masyvą, šis metodas grąžina parametre perduoto tipo objektų masyvą.

Norėdami susieti šeimą Nustatyti susieti HashSet, Medžių rinkinys Ir LinkedHashSet. Rinkiniuose Nustatyti Skirtingi diegimai naudoja skirtingą elementų saugojimo tvarką. „HashSet“ elementų tvarka optimizuota, kad būtų galima greitai ieškoti. TreeSet konteineryje saugomi objektai, surūšiuoti didėjimo tvarka. „LinkedHashSet“ saugo elementus tokia tvarka, kokia jie buvo pridėti.

HashSet duomenų rinkinys

HashSet konstruktoriai:

// Sukurkite tuščią rinkinį, kurio pradinė talpa yra 16 ir numatytasis apkrovos koeficientas 0,75 public HashSet(); // Aibės kūrimas iš kolekcijos elementų public HashSet(Collection c); // Sukurkite rinkinį su nurodyta pradine talpa ir // numatytuoju apkrovos koeficientu (0,75) public HashSet(int pradinė talpa); // Sukurkite rinkinį su nurodyta pradine talpa ir // apkrovos koeficientu public HashSet(int pradinisCapacity, float loadFactor);

HashSet metodai

  • viešas int dydis ()
  • viešoji loginė vertė yra tuščia()
  • viešas loginis priedas (O objektas)
  • viešoji loginė vertė „addAll“ (c rinkinys)
  • viešas loginis pašalinimas (O objektas)
  • vieša loginė vertė pašalinti viską (rinkinys c)
  • viešoji loginė vertė yra(O objektas)
  • vieša galia aišku ()
  • viešasis objekto klonas ()
  • viešasis iteratoriaus iteratorius()
  • viešasis objektas toArray()
  • vieša loginė vertė išlaikyti viską (rinkinys c)

HashSet yra metodų, panašių į ArrayList . Išimtis yra add(Object o) metodas, kuris prideda objektą tik tada, kai jo trūksta. Jei objektas pridedamas, pridėjimo metodas grąžina teisingą, kitu atveju false.

HashSet naudojimo pavyzdys:

HashSet hashSet = naujas maišos rinkinys (); hashSet.add("Bulvės"); hashSet.add("Morka"); hashSet.add("Runkeliai"); hashSet.add("Agurkai"); // Kitas įrašas neturėtų būti rinkinyje hashSet.add("Bulvės"); // Išspausdinkite rinkinio dydį į konsolę System.out.println("HashSet size = " + hashSet.size()); // Spausdinti Iterator įrašus į konsolę itr = hashSet.iterator(); while (itr.hasNext()) ( System.out.println(itr.next().toString()); )

Konsolėje turėtume matyti tik 4 įrašus. Reikėtų pažymėti, kad įrašų įtraukimo į rinkinį tvarka bus nenuspėjama. HashSet naudoja maišą, kad pagreitintų atgavimą.

Naudojimo pavyzdys HashSet su sveikosiomis reikšmėmis. Prie rinkinio pridedame reikšmes nuo 0 iki 9 iš 25 galimų atsitiktinai parinktų reikšmių – nebus dubliavimosi.

Atsitiktinis atsitiktinis = new Atsitiktinis(30); Nustatyti iset = naujas HashSet (); for(int i = 0; i< 25; i++) iset.add(random.nextInt(10)); // Вывести в консоль записи Iterator

Reikėtų pažymėti, kad įgyvendinimas HashSet nesinchronizuoja. Jei maišos rinkinį vienu metu pasiekia kelios gijos, o viena ar kelios gijos turi modifikuoti rinkinį, jis turi būti sinchronizuojamas išoriškai. Tai geriausia padaryti kuriant, kad būtų išvengta atsitiktinės nesinchronizuotos prieigos prie rinkinio:

Nustatyti set = Collections.synchronizedSet(new HashSet ());

LinkedHashSet duomenų rinkinys

Klasė LinkedHashSet paveldi HashSet nepridedant jokių naujų metodų ir palaiko susietą rinkinio elementų sąrašą ta tvarka, kuria jie buvo įterpti. Tai leidžia tvarkingai kartoti įterpimą į rinkinį.

LinkedHashSet konstruktoriai:

// Sukurkite tuščią rinkinį su pradine talpa (16) ir numatytąją apkrovos faktoriaus reikšmę (0,75) public LinkedHashSet() // Sukurkite rinkinį iš rinkinio elementų public LinkedHashSet(Collection c) // Sukurkite rinkinį su nurodytu pradiniu talpa ir faktoriaus vertė numatytoji apkrova (0,75) public LinkedHashSet(int pradinė talpa) // Sukurkite rinkinį su nurodyta pradine talpa ir apkrovos koeficientu public LinkedHashSet(int pradinė talpa, float loadFactor)

Taip pat kaip HashSet, LinkedHashSet nesinchronizuoja. Todėl naudojant šį įgyvendinimą programoje su daugybe gijų, iš kurių kai kurios gali keisti rinkinį, sinchronizavimas turėtų būti atliktas kūrimo etape:

Nustatyti set = Collections.synchronizedSet(new LinkedHashSet ());

TreeSet duomenų rinkinys

Klasė Medžių rinkinys sukuria kolekciją, kurioje elementams saugoti naudojamas medis. Objektai saugomi surūšiuota didėjimo tvarka.

TreeSet konstruktoriai:

// Sukurkite tuščią medžių rinkinį, surūšiuotą pagal natūralią // jo elementų tvarką TreeSet() // Sukurkite medžių rinkinį, kuriame būtų nurodytos rinkinio elementai, // surūšiuoti pagal natūralią elementų tvarką. TreeSet (Kolekcijac) // Sukurkite tuščią medžių rinkinį, surūšiuotą pagal palyginimo priemonę TreeSet(Comparatorkomparatorius) // Sukurkite medžio rinkinį su tais pačiais elementais ir naudodami // tą pačią tvarką kaip nurodytas surūšiuotas rinkinys TreeSet(SortedSet s)

„TreeSet“ metodai

  • loginis priedas (O objektas)
  • loginis addAll(Kolekcijac)
  • Objekto lubos (O objektas)
  • tuščias aiškus ()
  • TreeSet klonas ()
  • Palyginimo priemonėlygintuvas ()
  • loginis yra (O objektas)
  • Iteratorius descendingIterator()
  • NavigableSet descendingSet()
  • Pirmas objektas ()
  • Objekto aukštas (O objektas)
  • Rūšiuotas rinkinys ausinės (E e)
  • NavigableSet headSet (E e, loginis imtinai)
  • Objektas aukščiau (O objektas)
  • loginis yra tuščias()
  • Iteratorius iteratorius ()
  • Elastas ()
  • E žemesnis (E e)
  • E apklausaFirst()
  • E apklausa Paskutinė()
  • loginis pašalinimas (O objektas)
  • int dydis ()
  • Skirstytuvas skirstytuvas ()
  • NavigableSet poaibis (E nuo elemento, loginė vertė nuo imtinai, E iki elemento, loginė į imtinai)
  • Rūšiuotas rinkinys poaibis (E nuo elemento, E iki elemento)
  • Rūšiuotas rinkinys uodegos rinkinys (E iš elemento)
  • NavigableSet uodegos rinkinys (E iš elemento, loginis imtinai)
  • Toliau pateiktame pakeistame pavyzdyje iš naudojimo Medžių rinkinys Vertės bus išvedamos į konsolę užsakyta forma.

    Rūšiuotas rinkinys treeSet = naujas TreeSet (); treeSet.add("Runkeliai"); treeSet.add("Agurkai"); treeSet.add("Pomidorai"); treeSet.add("Bulvės"); treeSet.add("Morka"); // Šis įrašas neturėtų būti įtrauktas į aibę treeSet.add("Bulvės"); // Išspausdinkite rinkinio dydį į konsolę System.out.println("treeSet size = " + treeSet.size()); // Spausdinti Iteratoriaus įrašus į konsolę itr = treeSet.iterator(); while (itr.hasNext()) ( System.out.println(itr.next().toString()); ) Atsitiktinis atsitiktinis = new Atsitiktinis(30); Rūšiuotas rinkinys iset = naujas medžio rinkinys (); for(int i = 0; i< 25; i++) iset.add(random.nextInt(10)); // Вывести в консоль записи Iteratoritr = iset.iterator(); while (itr.hasNext()) ( System.out.println(itr.next().toString()); )

    Josephas Crawfordas, vienas iš mano skaitytojų, perskaitė straipsnį apie tai, kaip aš nemėgstu rašyti geterių ir seterių, ir pasiūlė, kad galėčiau naudoti magiškus __get ir __set metodus.
    Aš jums pasakysiu, kodėl nėra gera idėja juos naudoti įprastu būdu. Taip pat papasakosiu istoriją, kur jie tikrai pravertė – statinių tipų kūrimas PHP (dinamiška kalba).
    Tiems, kurie nėra susipažinę su __get ir __set metodais, tai yra du "stebuklingi" metodai, kurie veikia taip:
    class Animal ( funkcija __get($property) ( //... ) function __set($property, $value) (//... ) ) $cow = new Animal; $karvė->svoris = "1 tona"; // toks pat kaip $karvė->__set("svoris", "1 tona") print $cow->weight; // tas pats kaip spausdinti $ karvė->__get("svoris");

    Paprastai aukščiau pateikti metodai naudojami dinaminėms savybėms sukurti. Kokią išvadą iš to galima padaryti? Jei norite sukurti kokių nors atsitiktinių savybių, tiesiog naudokite maišą (dar žinomą kaip masyvas su raktais).
    Kuo geri geteriai ir seteriai?
    Pažiūrėkime:
    klasė Gyvūnas ( public $weightInKgs; ) $karvė = naujas gyvūnas; $karvė->svorisKgs = -100;

    Ką? Neigiamas svoris? Daugeliu požiūriu tai neteisinga.
    Karvė turi sverti ne mažiau nei 100 kg (manau, kad taip:). Per 1000 yra priimtina.
    Kaip galime užtikrinti tokį apribojimą?
    __get ir __set naudojimas yra gana greitas būdas.
    class Animal ( private $properties = array(); viešoji funkcija __get($name) ( if(!empty($this->properties[$name])) ( return $this->properties[$name]; ) else ( throw new Exception("Neapibrėžta nuosavybė ".$name." nuoroda."); ) ) viešoji funkcija __set($name, $value) (if($name == "svoris") ( if($value< 100) { throw new Exception("The weight is too small!") } } $this->savybės[$vardas] = $reikšmė; ) ) $karvė = naujas gyvūnas; $karvė->svorisKgs = -100; //meta Išimtį

    Ką daryti, jei turite klasę su 10–20 savybių ir jas patikrinate? Tokiu atveju bėdos neišvengiamos.
    viešoji funkcija __set($vardas, $value) ( ​​if($name == "svoris") ( if($value< 100) { throw new Exception("The weight is too small!") } if($this->svoris != $svoris) ( Shepherd::notifyOfWeightChange($karvė, $svoris); ) ) if($vardas == "kojos") ( if($value != 4) ( throw new Exception("Kojų skaičius yra per mažas arba per didelis") ) $this->numberOfLegs = $numberOfLegs; $this->numberOfHooves = $numberOfLegs; ) if($name == "milkType") ( .... supratote ... .) $this->ypatybės[$vardas] = $vertė; )

    Atvirkščiai, gautieji ir nustatytojai yra geriausi, kai kalbama apie duomenų patvirtinimą.
    class Animal ( privatus $svoris; privatus $numberOfLegs; privatus $numberOfHooves; viešas $slapyvardis; viešoji funkcija setNumberOfLegs($numberOfLegs) ( if ($numberOfLegs != 100) ( throw new Exception("Kojų skaičius per mažas arba per daug didelis"); ) $this->numberOfLegs = $numberOflegs; $this->numberOfHooves = $numberOfLegs; ) viešoji funkcija getNumberOfLegs() (grąžina $this->numberOfLegs; ) viešoji funkcija setWeight($weight) ( if ($weight)< 100) { throw new Exception("The weight is too small!"); } if($this->svoris != $svoris) ( Shepherd::notifyOfWeightChange($karvė, $svoris); ) $this->weight = $svoris; ) viešoji funkcija getWeight() ( grąžinti $this->weight; ) )

    Niekas neprilygsta nuorodų funkcijoms (gauti, nustatyti;) iš C#. Tikėtina, kad toks palaikymas greitai pasirodys PHP, bet kol kas neatsipalaiduokime...
    Kiekvienas metodas yra atsakingas tik už savo sritį, todėl kodą lengviau naršyti. Tai vis dar daug kodo, tačiau jis yra švaresnis nei __set versija. Yra geras euristinis metodas, kuris yra toks: jei jūsų metodas (funkcija) užima daugiau nei 1 ekraną, turite jį sutrumpinti. Taip kodą bus lengviau skaityti.
    Taip pat saugome tam tikrą verslo logiką. Kanopų visada bus lygiai tiek, kiek kojų, o pastebėję galvijų svorio pasikeitimą iš karto pranešime piemeniui.
    Kadangi mums nerūpi karvių slapyvardžiai ir jų netikriname, tegul duomenys būna vieši be geterių ir seterių.
    Vėlgi, aš tikrai nerašiau visų šių geterių ir seterių – PHP Storm tai padarė už mane. Aš tiesiog parašiau taip:
    klasės gyvūnas (privatus $svoris; privatus $numberOfLegs; )

    Ir paspaudė Alt+Insert -> Getters and setters. PHPStorm viską sugeneravo automatiškai.
    Dabar, kaip papildomą PHP Storm pranašumą, dirbdamas su geteriais ir nustatytojais turiu galimybę naudoti automatinio užbaigimo funkciją:

    __get atveju šios parinkties neturiu, galiu parašyti tik štai ką:
    $ karvė-> svoris = -100

    Dabar karvė „sveria“ (sveria) minus 100 kg.
    Galiu pamiršti, kad tai svoris kg, tiesiog parašykite svorį ir viskas veiks.
    Taigi, geteriai ir setteriai gali būti labai naudingi (bet vis tiek jų negarbinkite, jūs nesate „Java“ programuotojas). Jei norite tik nemokamų savybių, naudokite masyvą:
    $karvė = array("svoris" => 100, "kojos" => 4);

    Šį triuką atlikti daug lengviau nei __gauti ir __nustatyti.
    Bet jei norite būti tikri, kad jūsų duomenys visada turi tik galiojančias reikšmes, naudokite nustatymo priemones su patvirtinimu. Jei turite integruotą kūrimo aplinką (IDE), pvz., PHP Storm, jums patiks setteriai, nes jais taip paprasta naudotis. Vietoj $cow->setLegs() PHP Storm pakaks įvesti cosl. Taip Lengva! Nebėra rašybos klaidų ir galite pamatyti, kokių parametrų reikalauja metodas.
    __set metodas turi dar vieną trūkumą. Jis priima tik 1 parametrą. O jei reikia 2? Pavyzdžiui, kaip čia: $store1->setPrice("prekė-1", 100). Parduotuvėje reikia nustatyti prekės kainą. __set metodas neleis jums to padaryti, bet nustatytojas leis.

    mob_info