Kopier til udklipsholder

kvidreFacebook

offentlig, privat og beskyttet adgang – alle programmører er bekendt med dette koncept. Ikke noget særligt, vi arbejder med dem dagligt. Men som Ruby programmører, kender vi virkelig detaljerne?

Du kan tjekke dig selv med disse fem udsagn. Prøv at svare: sandt eller falsk.

erklæringer:

  1. offentlige metoder har ingen adgangskontrol – de kan kaldes udefra af klassedefinitionen ved forekomsten af den klasse eller det er underklasser.
  2. både beskyttede og private metoder kan ikke kaldes udefra af den definerende klasse.
  3. beskyttede metoder er tilgængelige fra underklassen, og private metoder er ikke.
  4. Private metoder i den definerende klasse kan påberåbes af enhver forekomst af denne klasse.
  5. offentlig adgang er standard.

vi vender tilbage til de rigtige svar i slutningen af denne artikel. Lad os nu gå dybere ind i nogle nuancer af offentlig, privat og beskyttet adgangskontrol. For at gøre det mere praktisk forberedte jeg prøvekode at lege med. Jeg anbefaler kloning af denne repo for at gøre det lettere at fortsætte med artiklen. Det er kun en fil. Hvis du først vil tænke på løsningen, skal du holde op med at køre koden.

Her er prøvekoden:

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 basisklassenRegionher sammen med to børneklasser:CountryogCityCityog Countryarve fra Region. Arv bruges til at demonstrere de offentlige, private og beskyttede detaljer. I slutningen af filen kan vi finde initialiseringsdel og 4 sektioner, som vi vil diskutere nedenfor. Se på filen for at blive fortrolig med koden.

Ok, lad os starte! I 3. afsnit af initialiseringen oprettes følgende objekter – wroclawsan_francisco og poland. Disse objekter vil blive brugt til demonstrationsformål i de kommende sektioner. Jeg foreslår at behandle alle disse segmenter separat. Du kan kommentere det bestemte afsnit, før du går til den næste. På den måde blokerer fejl ikke resten af output.

I sektion

emne: offentlig adgang.

i det første afsnitgreeting metoden påberåbes to gange: afwroclaw og afpoland objekter. Ikke noget særligt her. Offentlig adgang er ligetil. greeting er tilgængelig for sin klasses objekt (poland) og for sin børneklasses objekt (wroclaw).

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

konklusion: offentlig adgang er tydelig og intuitiv. Der er ingen begrænsninger. Det er også standardadgangsmodifikatoren.

II afsnit

emne: adgang til de private og beskyttede metoder udefra af den definerende klasse.

der er to vigtige metoder i dette afsnit: beskyttet name_info og privat population_info. Resultatet ser ud til at være intuitivt igen. wroclaw objekt har ingen adgang til hverken de private metoder eller de beskyttede. I begge tilfælde NoMethodError kastes.

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

konklusion: Private og beskyttede metoder kan ikke kaldes udefra af klassen. Adgangen er begrænset.

III sektion

emne: adgang til private og beskyttede metoder fra indersiden af den definerende klasse.

denne gang har vi City::own_greeting som bruger arvet beskyttet metode inde (name_info) og Country::own_greeting som bruger arvet privat metode inde (population_info). Både private og beskyttede metoder (selvom de er arvet) er tilgængelige inden for klassen. Så det er ikke det punkt, der adskiller privat fra Beskyttet adgang.

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

konklusion: Private og beskyttede metoder kan kaldes fra indersiden af den definerende klasse. Adgang er tilladt.

IV sektion

emne: faktisk forskel mellem private og beskyttede metoder.

IV sektion-flere uventede regler kan begynde at vises her.Du kan se 3 offentlige metoder der:

  • more_densely_populated?(other_region) – det bruger privatpopulation_density inde.
  • the_same_continent?(other_region) – det bruger beskyttet continent inde.
  • can_be_crowdy? – det bruger privat consider_as_densely_populated? inde.

lad os gennemgå koden trin for trin:

more_densely_populated?(other_region)

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

Hmm, det er interessant. Privat metode Region::population_densityer ikke blevet kaldt, selvom den er implementeret inde i Region klasse. Det lignende scenario er blevet arbejdet i III sektionen …

the_same_continent?(other_region)

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

denne fungerer. Nogen forskel her? Højre, the_same_continent? bruger beskyttet attribut – continent. Okay, lad os fortsætte.

can_be_courdy?

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

NoMethodError igen. Hmm, can_be_crowdy?bruger også privatconsider_as_densely_populated? metode. Lignende situation fungerede fint I III-sektionen. Så hvad sker der her?

det handler om modtageren.

dybest set er modtageren det objekt, hvis metode påberåbes. Lad os gå direkte til eksemplerne:

  • other_region.population_density ? – modtageren erother_region.
  • other_region.continent – modtageren er other_region.
  • self.consider_as_densely_populated? – modtageren er self.

og her er de vigtige ting, husk den regel:

Private metoder kan ikke kaldes med en eksplicit modtager.

Vær opmærksom på ordet ‘eksplicit’ her. Forenkling af denne erklæring – du kan ikke ringe til privat metode ved at skrive påkaldelsen som denne – object.some_method. Du skal bruge pure some_method. I sidstnævnte tilfælde bruger Ruby den implicitte modtager, som altid er self. Uanset det faktum kan du stadig ikke kalde en privat metode ved self.some_method, fordi det stadig er en eksplicit modtager, og regler er regler:)

gå tilbage til vores metoder:

  • other_region.population_density ? – den eksplicitte modtager er til stede, og metoden er privat – NoMethodError
  • other_region.continent – den eksplicitte modtager er til stede, og attributten er beskyttet – OK
  • self.consider_as_densely_populated? – den eksplicitte modtager er til stede, og metoden er privat – NoMethodError

konklusion: Dette er den faktiske skelnen mellem privat og beskyttet. Private metoder kan ikke kaldes med en eksplicit modtager, og beskyttede kan. Baseret på min erfaring bruges beskyttede metoder sjældent blandt Ruby-kodelinjer, men de kan være nyttige, når man sammenligner parametre, for eksempel når vi vil begrænse adgangen til attributten, men stadig vil bruge den i sammenligningsmetoden.

Jeg håber, at adgangskontrolreglerne er meget mere klare nu. Jeg opfordrer dig til at få dine hænder beskidte med koden, hvis du ikke allerede havde gjort det. Teori har tendens til at blive glemt, hvis den ikke er beviset.

i sidste ende, som jeg lovede-svar på udsagnene:

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

Resume

jeg har skrevet denne artikel, fordi det for mig også var overraskende, hvordan offentlig, privat og beskyttet adgang faktisk fungerer i Ruby. De enkleste ting er de sværeste at forstå, eller i det mindste kan de være. Jeg håber virkelig, at denne artikel var nyttigt for dig. Eller måske var du opmærksom på adgangsreglerne, før du læste den. Del dine tanker i kommentarerne, Jeg er meget nysgerrig efter dem. Du kan også se på dokumenterne. Du finder alle disse detaljer der 🙂

Deltag

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.