Kopioi leikepöydälle

TwitterFacebook

julkinen, yksityinen ja suojattu pääsy – kaikki ohjelmoijat tuntevat kyseisen konseptin. Ei mitään erityistä, työskentelemme heidän kanssaan päivittäin. Mutta Ruby-ohjelmoijina, tiedämmekö todella yksityiskohdat?

voit tarkistaa itsesi näillä viidellä lauseella. Yritä vastata: totta vai epätosi.

lauseet:

  1. julkisissa menetelmissä ei ole kulunvalvontaa – niitä voidaan kutsua luokkamääritelmän ulkopuolelta kyseisen luokan tai sen alaluokkien esiintymän mukaan.
  2. sekä suojattuja että yksityisiä menetelmiä ei voida kutsua määrittävän luokan ulkopuolelta.
  3. suojattuja menetelmiä voi käyttää alaluokasta, yksityisiä menetelmiä ei.
  4. määritellyn luokan yksityisiin menetelmiin voi vedota mikä tahansa kyseisen luokan esiintymä.
  5. julkisuus on oletusarvo.

palaamme oikeisiin vastauksiin tämän artikkelin lopussa. Nyt mennään syvemmälle joitakin vivahteita julkisen, yksityisen ja suojattu kulunvalvonta. Jotta se olisi käytännöllisempää olen valmis näyte koodi pelata. Suosittelen Kloonaus tämä repo jotta jatkaminen artikkelin helpompaa. Se on vain yksi kansio. Jos haluat ajatella ratkaisu ensin, sitten lykätä käynnissä koodi.

tässä on esimerkkikoodi:

class Region attr_accessor :name def initialize(name, population, area_size, continent) self.name = name self.population = population self.area_size = area_size self.continent = continent end def greeting puts name_info + population_info end def more_densely_populated?(other_region) result = population_density > other_region.population_density ? 'more' : 'less' puts "#{name} is #{result} densely populated than #{other_region.name}." end def the_same_continent?(other_region) if continent.eql?(other_region.continent) puts "#{name} and #{other_region.name} lie in the same continent." else puts "#{name} and #{other_region.name} lie in the different continents." end end def can_be_crowdy? if self.consider_as_densely_populated? puts "#{name} can be crowdy." else "There is enough space in the #{name}." end end protected attr_accessor :continent def name_info "Hello, I'm #{name}!" end private attr_accessor :population, :area_size def population_info " #{population} people live here." end def population_density population / area_size end def consider_as_densely_populated? population_density > self.class::HIGH_POPULATION_DENSITY endendclass Country < Region HIGH_POPULATION_DENSITY = 300 def own_greeting puts "The country name: #{name}." + population_info endendclass City < Region HIGH_POPULATION_DENSITY = 3000 def own_greeting puts name_info + " The population: #{population} people." endend# initializationwroclaw = City.new('Wrocław', 638_000, 293, 'Europe')san_francisco = City.new('San Francisco', 884_000, 121, 'Northern America')poland = Country.new('Poland', 38_000_000, 312_000, 'Europe')# I sectionwroclaw.greetingpoland.greeting# II sectionwroclaw.name_infowroclaw.population_info# III sectionwroclaw.own_greetingpoland.own_greeting# IV sectionwroclaw.more_densely_populated?(san_francisco)wroclaw.the_same_continent?(san_francisco)san_francisco.can_be_crowdy?

näet perusluokan Region täällä yhdessä kahden lapsiluokan kanssa: Country ja CityCity ja Country perii Region. Perintöä käytetään osoittamaan julkisia, yksityisiä ja suojattuja yksityiskohtia. Lopussa tiedoston, löydämme alustus osa ja 4 osiot, joista keskustelemme alla. Tutustu tiedostoon tutustuaksesi koodiin.

Ok, aloitetaan! Alustuksen 3. jaksossa luodaan seuraavat oliot – wroclawsan_francisco ja poland. Näitä esineitä käytetään esittelytarkoituksiin tulevissa osissa. Ehdotan, että käsittelemme kaikki nämä segmentit erikseen. Voit kommentoida tiettyä osiota ennen kuin siirryt seuraavaan. Näin virheet eivät estä loppulähtöä.

I jakso

aihe: julkinen pääsy.

ensimmäisessä jaksossa greeting menetelmään vedotaan kahdesti: wroclaw ja poland objektit. Täällä ei ole mitään erikoista. Julkisuus on suoraviivaista. greeting on saatavilla luokkansa objektille (poland) ja lapsiluokkansa objektille (wroclaw).

Hello, I'm Wrocław! 638000 people live here.Hello, I'm Poland! 38000000 people live here.

johtopäätös: julkisuus on ilmeistä ja intuitiivista. Rajoituksia ei ole. Myös, se on oletuksena access modifier.

II jakso

aihealue: pääsy yksityisiin ja suojattuihin menetelmiin määrittelevän luokan ulkopuolelta.

siinä on kaksi tärkeää menetelmää: suojattu name_info ja yksityinen population_info. Tulos tuntuu taas intuitiiviselta. wroclaw Objektilla ei ole pääsyä sen paremmin yksityisiin kuin suojattuihin menetelmiin. Molemmissa tapauksissa NoMethodError heitetään.

protected method `name_info' called for #<City:0x...> (NoMethodError)private method `population_info' called for #<City:0x...> (NoMethodError)

johtopäätös: yksityisiä ja suojattuja menetelmiä ei voi kutsua luokan ulkopuolelta. Pääsy on rajoitettu.

III jakso

aihealue: pääsy yksityisiin ja suojattuihin menetelmiin määrittelevän luokan sisältä.

tällä kertaa meillä on City::own_greeting joka käyttää perittyä suojattua menetelmää sisällä (name_info) ja Country::own_greeting joka käyttää perittyä yksityistä menetelmää sisällä (population_info). Luokan sisällä on käytettävissä sekä yksityisiä että suojattuja menetelmiä (vaikka ne periytyisivätkin). Se ei siis ole piste, joka erottaa yksityisen ja suojatun pääsyn.

Hello, I'm Wrocław! The population: 638000 people.The country name: Poland. 38000000 people live here.

johtopäätös: yksityisiä ja suojattuja menetelmiä voidaan kutsua määrittelyluokan sisältä. Sisäänpääsy on sallittu.

IV jakso

aihealue: todellinen ero yksityisten ja suojattujen menetelmien välillä.

iv jakso – lisää yllättäviä sääntöjä voi alkaa ilmestyä täällä.Siellä voi nähdä 3 julkista menetelmää:

  • more_densely_populated?(other_region) – se käyttää yksityistä population_density sisällä.
  • the_same_continent?(other_region) – se käyttää suojattua continent sisällä.
  • can_be_crowdy? – se käyttää yksityistä consider_as_densely_populated? sisällä.

käydään koodi läpi vaihe vaiheelta:

more_densely_populed?(other_ Region)

wroclaw.more_densely_populated?(san_francisco)=> private method `population_density' called for #<City:0x...> (NoMethodError)

hmm, se on mielenkiintoista. Yksityistapaa Region::population_density ei ole kutsuttu, vaikka se on toteutettu Region luokan sisällä. Vastaavaa skenaariota on työstetty III jaksossa …

the_same_continent?(other_ Region)

wroclaw.the_same_continent?(san_francisco)=> Wrocław and San Francisco lie in the different continents.

Tämä toimii. Onko tässä mitään eroa? Oikealla the_same_continent? käyttää suojattua attribuuttia – continent. Jatketaan.

can_be_crowdy?

san_francisco.can_be_crowdy?=> private method `consider_as_densely_populated?' called for #<City:0x...> (NoMethodError)

NoMethodError uudelleen. Hmm, can_be_crowdy? käyttää myös yksityistä consider_as_densely_populated? menetelmää. Samanlainen tilanne toimi hienosti III-osiossa. Mitä täällä tapahtuu?

kyse on vastaanottajasta.

periaatteessa vastaanottaja on olio, jonka menetelmään vedotaan. Mennään suoraan esimerkkeihin:

  • other_region.population_density ? – vastaanottaja on other_region.
  • other_region.continent – vastaanottaja on other_region.
  • self.consider_as_densely_populated? – vastaanottaja on self.

ja tässä on se tärkeä juttu, muista, että sääntö:

yksityisiä menetelmiä ei voi kutsua eksplisiittisellä vastaanottimella.

kiinnitä huomiota sanaan ”eksplisiittinen” tässä. Tämän lausekkeen yksinkertaistaminen-et voi kutsua yksityistä menetelmää kirjoittamalla kutsumuksen näin – object.some_method. Pitää käyttää puhdasta some_method. Jälkimmäisessä tapauksessa Ruby käyttää implisiittistä vastaanottajaa, joka on aina self. Siitä huolimatta yksityistä metodia ei voi edelleenkään kutsua self.some_method, koska se on edelleen eksplisiittinen vastaanotin, ja säännöt ovat sääntöjä:)

palataan metodeihimme:

  • other_region.population_density ? – eksplisiittinen vastaanotin on läsnä ja menetelmä on yksityinen – NoMethodError
  • other_region.continent – eksplisiittinen vastaanotin on läsnä ja attribuutti on suojattu – OK

  • self.consider_as_densely_populated? – eksplisiittinen vastaanottaja on läsnä ja menetelmä on yksityinen – NoMethodError

johtopäätös: tämä on todellinen ero yksityisen ja suojatun välillä. Yksityisiä menetelmiä ei voida kutsua nimenomaisella vastaanottimella ja suojattuja voidaan. Kokemukseni perusteella suojattuja menetelmiä käytetään harvoin Ruby-koodirivien joukossa, mutta ne voivat olla hyödyllisiä parametrejä vertailtaessa, esimerkiksi silloin, kun haluamme rajoittaa attribuutin käyttöoikeutta, mutta haluamme silti käyttää sitä vertailumenetelmässä.

toivon, että kulunvalvontasäännöt ovat nyt paljon selkeämmät. Kehotan sinua likaamaan kätesi koodin kanssa, jos et olisi tehnyt sitä jo. Teoria yleensä unohdetaan, jos sitä ei oikolueta.

lopussa, kuten lupasin – vastauksia lausuntoihin:

  1. TRUE
  2. True
  3. FALSE
  4. TRUE
  5. TRUE
  6. True
  7. Yhteenveto

    olen kirjoittanut tämän artikkelin, koska minulle oli myös yllättävää, miten julkinen, yksityinen ja suojattu pääsy todellisuudessa toimivat Rubyssa. Yksinkertaisimmat asiat ovat vaikeimpia ymmärtää, tai ainakin ne voivat olla. Toivon todella, että tämä kirjoitus oli hyödyllinen sinulle. Tai ehkä olit tietoinen pääsysäännöistä ennen sen lukemista. Jaa ajatuksesi kommenteissa, olen hyvin utelias niistä. Voit vilkaista myös dokumentteja. Löydät kaikki nämä tiedot sieltä 🙂

    join

Vastaa

Sähköpostiosoitettasi ei julkaista.