Kopiera till Urklipp

TwitterFacebook

offentlig, privat och skyddad åtkomst – alla programmerare är bekanta med det konceptet. Inget speciellt, vi arbetar med dem dagligen. Men som Ruby programmerare, vet vi verkligen detaljerna?

Du kan kontrollera dig själv med dessa fem uttalanden. Försök att svara: sant eller falskt.

uttalanden:

  1. offentliga metoder har ingen åtkomstkontroll – de kan anropas från utsidan av klassdefinitionen av förekomsten av den klassen eller det är underklasser.
  2. både skyddade och privata metoder kan inte anropas från utsidan av den definierande klassen.
  3. skyddade metoder är tillgängliga från underklassen och privata metoder är inte.
  4. privata metoder för den definierande klassen kan åberopas av någon instans av den klassen.
  5. allmän åtkomst är standard.

Vi kommer tillbaka till rätt svar i slutet av den här artikeln. Låt oss nu gå djupare in i några nyanser av offentlig, privat och skyddad åtkomstkontroll. För att göra det mer praktiskt förberedde jag provkod att leka med. Jag rekommenderar kloning av denna repo för att göra det lättare att fortsätta med artikeln. Det är bara en fil. Om du vill tänka på lösningen först, vänta sedan med att köra koden.

här är exempelkoden:

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?

Du kan se basklassen Region här tillsammans med två barnklasser: Country och CityCity och Country ärva från Region. Arv används för att visa offentliga, privata och skyddade detaljer. I slutet av filen kan vi hitta initialiseringsdel och 4 avsnitt som vi kommer att diskutera nedan. Ta en titt på filen för att bekanta dig med koden.

Ok, låt oss börja! I 3: e delen av initialiseringen skapas följande objekt – wroclawsan_francisco och poland. Dessa objekt kommer att användas för demonstrationsändamål i de kommande avsnitten. Jag föreslår att alla dessa segment behandlas separat. Du kan kommentera det specifika avsnittet innan du går till nästa. På så sätt kommer fel inte att blockera resten av utmatningen.

I avsnitt

ämne: allmänhetens tillgång.

i det första avsnittetgreeting metoden åberopas två gånger: avwroclaw och avpoland objekt. Inget speciellt här. Allmänhetens tillgång är enkel. greeting är tillgängligt för klassens objekt (poland) och för dess underordnade klassens objekt (wroclaw).

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

slutsats: allmänhetens tillgång är uppenbar och intuitiv. Det finns inga begränsningar. Det är också standardåtkomstmodifieraren.

II avsnitt

ämne: tillgång till privata och skyddade metoder från utsidan av den definierande klassen.

det finns två viktiga metoder i det avsnittet: skyddad name_info och privat population_info. Resultatet verkar vara intuitivt igen. wroclaw objektet har ingen tillgång till varken de privata metoderna eller de skyddade. I båda fallen kastas NoMethodError.

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

slutsats: privata och skyddade metoder kan inte anropas från utsidan av klassen. Åtkomst är begränsad.

III avsnitt

ämne: tillgång till privata och skyddade metoder från insidan av den definierande klassen.

den här gången har vi City::own_greeting som använder ärftlig skyddad metod inuti (name_info) och Country::own_greeting som använder ärftlig privat metod inuti (population_info). Både privata och skyddade metoder (även om de ärvs) är tillgängliga inom klassen. Så det är inte den punkt som skiljer privat från skyddad åtkomst.

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

slutsats: privata och skyddade metoder kan anropas från insidan av den definierande klassen. Åtkomst är tillåten.

IV avsnitt

ämne: faktisk skillnad mellan privata och skyddade metoder.

iv avsnitt – mer oväntade regler kan börja visas här.Du kan se 3 offentliga metoder där:

  • more_densely_populated?(other_region) – den använder privat population_density inuti.
  • the_same_continent?(other_region) – den använder skyddad continent inuti.
  • can_be_crowdy? – den använder privat consider_as_densely_populated? inuti.

Låt oss gå igenom koden steg för steg:

more_densely_populated?(other_region)

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

Hmm, det är intressant. Privat metod Region::population_density har inte anropats, även om den implementeras i klassen Region. Det liknande scenariot har arbetats I III-avsnittet …

the_same_continent?(other_region)

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

den här fungerar. Någon skillnad här? Höger, the_same_continent? använder skyddat attribut – continent. Okej, låt oss fortsätta.

can_be_crowdy?

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

NoMethodError igen. Hmm, can_be_crowdy?använder också privatconsider_as_densely_populated? metod. Liknande situation fungerade bra i III-avsnittet. Så vad händer här?

det handlar om mottagaren.

i princip är mottagaren objektet vars metod åberopas. Låt oss gå direkt till exemplen:

  • other_region.population_density ? – mottagaren är other_region.
  • other_region.continent – mottagaren ärother_region.
  • self.consider_as_densely_populated? – mottagaren ärself.

och här är de viktiga sakerna, kom ihåg den regeln:

privata metoder kan inte anropas med en explicit mottagare.

Var uppmärksam på ordet ”explicit” här. Förenkla detta uttalande-Du kan inte ringa privat metod genom att skriva Anropet så här – object.some_method. Du måste använda ren some_method. I det senare fallet använder Ruby den implicita mottagaren, som alltid är self. Oavsett det faktum kan du fortfarande inte ringa en privat metod med self.some_method, för det är fortfarande en explicit mottagare och regler är regler:)

gå tillbaka till våra metoder:

  • other_region.population_density ? – den explicita mottagaren är närvarande och metoden är privat – NoMethodError
  • other_region.continent – den explicita mottagaren är närvarande och attributet är skyddat – OK

  • self.consider_as_densely_populated? – den explicita mottagaren är närvarande och metoden är privat – NoMethodError

slutsats: detta är den faktiska skillnaden mellan privat och skyddad. Privata metoder kan inte anropas med en explicit mottagare och skyddade kan. Baserat på min erfarenhet används skyddade metoder sällan bland Ruby-kodlinjer, men de kan vara användbara när man jämför parametrar, till exempel när vi vill begränsa åtkomsten till attributet men ändå vill använda det i jämförelsemetoden.

Jag hoppas att reglerna för åtkomstkontroll är mycket tydligare nu. Jag uppmuntrar dig att smutsa händerna med koden om du inte redan hade gjort det. Teorin tenderar att glömmas om den inte är bevisad.

i slutändan, som jag lovade-svar på uttalandena:

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

sammanfattning

Jag har skrivit den här artikeln eftersom det för mig också var förvånande hur offentlig, privat och skyddad åtkomst faktiskt fungerar i Ruby. De enklaste sakerna är de svåraste att förstå, eller åtminstone kan de vara. Jag hoppas verkligen att den här artikeln var till hjälp för dig. Eller kanske var du medveten om åtkomstreglerna innan du läste den. Dela dina tankar i kommentarerna, jag är väldigt nyfiken på dem. Du kan också titta på dokumenten. Du hittar alla dessa detaljer där 🙂

gå med

Lämna ett svar

Din e-postadress kommer inte publiceras.