Copiați în clipboard

TwitterFacebook

acces Public, privat și protejat – toți programatorii sunt familiarizați cu acest concept. Nimic special, lucrăm cu ei zilnic. Cu toate acestea, ca programatori Ruby, știm cu adevărat detaliile?

vă puteți verifica cu aceste cinci afirmații. Încercați să răspundeți: adevărat sau fals.

declarații:

  1. metodele publice nu au control de acces – ele pot fi apelate din afara definiției clasei de către instanța acelei clase sau subclase.
  2. atât metodele protejate, cât și cele private nu pot fi apelate din afara clasei definitorii.
  3. metodele protejate sunt accesibile din subclasă, iar metodele private nu sunt.
  4. metodele Private ale clasei definitorii pot fi invocate de orice instanță a acelei clase.
  5. accesul Public este cel implicit.

vom reveni la răspunsurile corecte la sfârșitul acestui articol. Deocamdată, să aprofundăm câteva nuanțe ale controlului accesului public, privat și protejat. Pentru a face mai practic am pregătit codul de probă pentru a juca cu. Vă recomandăm clonarea acest repo pentru a face continuarea cu articolul mai ușor. E doar un dosar. Dacă doriți să vă gândiți mai întâi la soluție, atunci nu mai rulați codul.

iată exemplul de cod:

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?

puteți vedea clasa de bază Region aici împreună cu două clase de copii: Country și CityCity șiCountry moștenesc de laRegion. Moștenirea este utilizată pentru a demonstra detaliile publice, private și protejate. La sfârșitul fișierului, putem găsi partea de inițializare și 4 secțiuni pe care le vom discuta mai jos. Aruncați o privire la fișier pentru a vă familiariza cu codul.

Ok, să începem! În secțiunea A 3 – A a inițializării, sunt create următoarele obiecte – wroclawsan_francisco și poland. Aceste obiecte vor fi folosite în scopuri demonstrative în secțiunile viitoare. Vă sugerez să tratați toate aceste segmente separat. Puteți comenta secțiunea specială înainte de a trece la următoarea. În acest fel, erorile nu vor bloca restul ieșirii.

Secțiunea I

subiect: acces Public.

în prima secțiunegreeting metoda este invocată de două ori: dewroclaw și depoland obiecte. Nimic special aici. Accesul publicului este simplu. greeting este accesibil pentru obiectul clasei sale (poland) și pentru obiectul clasei sale copil (wroclaw).

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

concluzie: accesul Public este evident și intuitiv. Nu există restricții. De asemenea, este modificatorul de acces implicit.

II secțiunea

subiect: accesul la metodele private și protejate din afara clasei definitorii.

există două metode importante în acea secțiune: protejatname_info și privatpopulation_info. Rezultatul pare să fie din nou intuitiv. wroclaw obiectul nu are acces nici la metodele private, nici la cele protejate. În ambele cazuriNoMethodError este aruncat.

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

concluzie: metodele Private și protejate nu pot fi apelate din afara clasei. Accesul este restricționat.

secțiunea III

subiect: accesul la metode private și protejate din interiorul clasei definitorii.

de data aceasta avemCity::own_greetingcare folosește metoda protejată moștenită în interior (name_info) șiCountry::own_greetingcare folosește metoda privată moștenită în interior (population_info). Atât metodele private, cât și cele protejate (chiar dacă sunt moștenite) sunt accesibile în interiorul clasei. Deci nu este punctul care distinge accesul privat de cel protejat.

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

concluzie: metodele Private și protejate pot fi apelate din interiorul clasei definitorii. Accesul este permis.

secțiunea IV

subiect: diferența reală între metodele private și cele protejate.

secțiunea IV – reguli mai neașteptate pot începe să apară aici.Puteți vedea 3 metode publice acolo:

  • more_densely_populated?(other_region) – folosește privatpopulation_density în interior.
  • the_same_continent?(other_region) – folosește protejatcontinent în interior.
  • can_be_crowdy? – se folosește privatconsider_as_densely_populated? interior.

să parcurgem codul pas cu pas:

more_densely_populated?(other_region)

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

Hmm, asta e interesant. Metoda privatăRegion::population_densitynu a fost apelată, chiar dacă este implementată în clasaRegion. Scenariul similar a fost lucrat în secțiunea III …

the_same_continent?(other_region)

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

Acesta funcționează. Vreo diferență aici? Corect,the_same_continent? folosește atributul protejat – continent. Bine, să continuăm.

can_be_crowdy?

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

NoMethodError din nou. Hmm, can_be_crowdy? folosește și metoda privată consider_as_densely_populated?. Situație similară a fost de lucru bine în secțiunea III. Deci, ce se întâmplă aici?

este vorba despre receptor.

practic receptorul este obiectul a cărui metodă este invocată. Să mergem direct la exemple:

  • other_region.population_density ? – receptorul esteother_region.
  • other_region.continent – receptorul esteother_region.
  • self.consider_as_densely_populated? – receptorul esteself.

și iată lucrurile importante, amintiți-vă că regula:

metodele Private nu pot fi apelate cu un receptor explicit.

acordați atenție cuvântului „explicit” aici. Simplificarea acestei declarații – nu puteți apela metoda privată scriind invocarea astfel – object.some_method. Trebuie să utilizați pur some_method. În acest din urmă caz, Ruby folosește receptorul implicit, care este întotdeauna self. Indiferent de acest fapt, încă nu puteți apela o metodă privată prin self.some_method, deoarece este încă un receptor explicit, iar regulile sunt reguli:)

revenind la metodele noastre:

  • other_region.population_density ? – receptorul explicit este prezent și metoda este privată – NoMethodError
  • other_region.continent – receptorul explicit este prezent și atributul este protejat – OK
  • self.consider_as_densely_populated? – receptorul Explicit este prezent și metoda este privată – NoMethodError

concluzie: aceasta este distincția reală între privat și protejat. Metodele Private nu pot fi apelate cu un receptor explicit, iar cele protejate pot. Pe baza experienței mele, metodele protejate sunt rareori utilizate printre liniile de cod Ruby, dar pot fi utile în timp ce comparăm parametrii, de exemplu, atunci când dorim să restricționăm accesul la atribut, dar totuși dorim să îl folosim în metoda de comparație.

sper că regulile de control al accesului sunt mult mai clare acum. Vă încurajez să vă murdăriți mâinile cu codul dacă nu ați fi făcut-o deja. Teoria tinde să fie uitată dacă nu este dovedită.

în cele din urmă, așa cum am promis-răspunsuri la declarațiile:

  1. TRUE
  2. true
  3. FALSE
  4. FALSE
  5. TRUE

rezumat

am scris acest articol pentru că pentru mine a fost surprinzător și modul în care accesul public, privat și protejat funcționează efectiv în Ruby. Cele mai simple lucruri sunt cele mai greu de înțeles, sau cel puțin pot fi. Sper cu adevărat că acest articol v-a fost de ajutor. Sau poate, ați fost conștienți de regulile de acces înainte de a le citi. Împărtășiți-vă gândurile în comentarii, sunt foarte curios de ele. Puteți arunca o privire la docs prea. Veți găsi toate aceste detalii acolo 🙂

Alăturați-vă

Lasă un răspuns

Adresa ta de email nu va fi publicată.