Kopier til utklippstavlen

TwitterFacebook

Offentlig, privat og beskyttet tilgang – alle programmerere er kjent med dette konseptet. Ikke noe spesielt, vi jobber med dem på en daglig basis. Men Som Ruby programmerere, vet vi virkelig detaljene?

du kan sjekke deg selv med disse fem utsagnene. Prøv å svare: SANT eller FALSKT.

Uttalelser:

  1. Offentlige metoder har ingen tilgangskontroll – De kan kalles fra utsiden av klassedefinisjonen ved forekomsten av den klassen eller det er underklasser.
  2. både beskyttede og private metoder kan ikke kalles fra utsiden av den definerende klassen.
  3. Beskyttede metoder er tilgjengelige fra underklassen, og private metoder er ikke Tilgjengelige.
  4. Private metoder for den definerende klassen kan påberopes av enhver forekomst av den klassen.
  5. Offentlig tilgang er standard.

vi kommer tilbake til de riktige svarene på slutten av denne artikkelen. For nå la oss gå dypere inn i noen nyanser av offentlig, privat og beskyttet tilgangskontroll. For å gjøre det mer praktisk forberedte jeg prøvekode å leke med. Jeg anbefaler kloning denne repo å gjøre fortsetter med artikkelen enklere. Det er bare en fil. Hvis du vil tenke på løsningen først, så hold av å kjøre koden.

her er eksempelkoden:

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 grunnklassenRegionher sammen med to barneklasser:CountryogCityCityogCountryarve fraRegion. Arv brukes til å demonstrere offentlige, private og beskyttede detaljer. På slutten av filen finner vi initialiseringsdel og 4 seksjoner som vi diskuterer nedenfor. Ta en titt på filen for å bli kjent med koden.

Ok, la oss starte! I 3.del av initialiseringen opprettes følgende objekter – wroclawsan_francisco og poland. Disse objektene vil bli brukt til demonstrasjonsformal i de kommende seksjonene. Jeg foreslår at du behandler alle disse segmentene separat. Du kan kommentere den aktuelle delen før du går til neste. På den måten vil feil ikke blokkere resten av utgangen.

I Seksjon

Emne: Offentlig tilgang.

i den første delen greeting metoden påberopes to ganger: avwroclaw og avpoland objekter. Ikke noe spesielt her. Offentlig tilgang er enkel. greeting er tilgjengelig for klassens objekt (poland) og for klassens objekt (wroclaw).

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

Konklusjon: Offentlig tilgang er tydelig og intuitiv. Det er ingen begrensninger. Det er også standard tilgangsmodifikator.

Ii Seksjon

Emne: Tilgang til private og beskyttede metoder fra utsiden av den definerende klassen.

det er to viktige metoder i den delen: beskyttet name_info og privat population_info. Resultatet ser ut til å være intuitivt igjen. wroclaw objektet har ingen tilgang til verken de private metodene eller de beskyttede. I begge tilfeller kastesNoMethodError.

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

Konklusjon: Private og beskyttede metoder kan ikke kalles fra utsiden av klassen. Tilgangen er begrenset.

III Seksjon

Emne: Tilgang til private og beskyttede metoder fra innsiden av den definerende klassen.

Denne gangen har viCity::own_greeting som bruker arvet beskyttet metode inne (name_info) og Country::own_greeting som bruker arvet privat metode inne (population_info). Både private og beskyttede metoder (selv om de er arvet) er tilgjengelige i klassen. Så det er ikke poenget som skiller privat fra beskyttet tilgang.

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

Konklusjon: Private og beskyttede metoder kan kalles fra innsiden av den definerende klassen. Tilgang er tillatt.

IV Seksjon

Emne: Faktisk forskjell mellom private og beskyttede metoder.

IV Seksjon – flere uventede regler kan begynne å vises her.Du kan se 3 offentlige metoder der:

  • more_densely_populated?(other_region) – den bruker privat population_density inne.
  • the_same_continent?(other_region) – den bruker beskyttetcontinent inne.
  • can_be_crowdy? – den bruker privat consider_as_densely_populated? inne.

La oss gå gjennom koden trinnvis:

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 metodeRegion::population_density har ikke blitt kalt, selv om den er implementert iRegion – klassen. Det samme scenariet har blitt jobbet I III-delen…

the_same_continent?(other_region)

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

denne fungerer. Noen forskjell her? Høyre,the_same_continent? bruker beskyttet attributt – continent. Ok, la oss fortsette.

can_be_crowdy?

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

NoMethodErrorigjen. Hmm,can_be_crowdy?bruker også privatconsider_as_densely_populated?metode. Lignende situasjon fungerte fint I III-delen. Så hva skjer her?

det handler om mottakeren.

i Utgangspunktet er mottakeren objektet hvis metode er påkalt. La oss gå rett til eksemplene:

  • other_region.population_density ? – mottakeren er other_region.
  • other_region.continent – mottakeren er other_region.
  • self.consider_as_densely_populated? – mottakeren er self.

og her er viktige ting, husk at regelen:

Private metoder kan ikke kalles med en eksplisitt mottaker.

Vær oppmerksom på ordet ‘eksplisitt’ her. Forenkle denne setningen – du kan ikke ringe privat metode ved å skrive påkallingen som dette- object.some_method. Du må bruke ren some_method. I sistnevnte tilfelle Bruker Ruby den implisitte mottakeren, som alltid er self. Uansett det faktum, kan du fortsatt ikke ringe en privat metode ved self.some_method, fordi det fortsatt er en eksplisitt mottaker, og regler er regler:)

Går tilbake til våre metoder:

  • other_region.population_density ? – den eksplisitte mottakeren er til stede og metoden er privat – NoMethodError
  • other_region.continent – den eksplisitte mottakeren er til stede og attributtet er beskyttet – OK

  • self.consider_as_densely_populated? – den eksplisitte mottakeren er til stede og metoden er privat – NoMethodError

konklusjon: dette er selve skillet mellom privat og beskyttet. Private metoder kan ikke kalles med en eksplisitt mottaker og beskyttede kan. Basert på min erfaring brukes beskyttede metoder sjelden blant Ruby-kodelinjer, men de kan være nyttige når man sammenligner parametere, for eksempel når vi vil begrense tilgangen til attributtet, men fortsatt vil bruke det i sammenligningsmetoden.

jeg håper at adgangskontrollreglene er mye tydeligere nå. Jeg oppfordrer deg til å få hendene skitne med koden hvis du ikke hadde gjort det allerede. Teori har en tendens til å bli glemt hvis det ikke er bevis.

Til slutt, som jeg lovet-svar på uttalelsene:

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

Sammendrag

jeg har skrevet denne artikkelen fordi for meg var det også overraskende hvordan offentlig, privat og beskyttet tilgang faktisk fungerer I Ruby. De enkleste tingene er de vanskeligste å forstå, eller i det minste kan de være. Jeg håper virkelig at denne artikkelen var nyttig for deg. Eller kanskje du var klar over tilgangsreglene før du leste den. Del dine tanker i kommentarene, jeg er veldig nysgjerrig på dem. Du kan også ta en titt på docs. Du finner alle disse detaljene der 🙂

bli med

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.