kopiëren naar klembord

TwitterFacebook

publieke, private en beveiligde toegang – alle programmeurs zijn bekend met dat concept. Niets bijzonders, we werken dagelijks met hen samen. Echter, als Ruby programmeurs, weten we echt de details?

u kunt uzelf controleren met deze vijf statements. Probeer te antwoorden: waar of onwaar.

Statements:

  1. openbare methoden hebben geen Toegangscontrole – ze kunnen worden aangeroepen van buiten de klasse definitie door de instantie van die klasse of zijn subklassen.
  2. zowel beschermde als private methoden kunnen niet worden aangeroepen van buiten de definiërende klasse.
  3. beschermde methoden zijn toegankelijk vanuit de subklasse en particuliere methoden niet.
  4. Private methoden van de definiërende klasse kunnen door elke instantie van die klasse worden aangeroepen.
  5. publieke toegang is de standaard.

We zullen aan het eind van dit artikel terugkomen op de juiste antwoorden. Laten we nu dieper ingaan op enkele nuances van publieke, private en beschermde Toegangscontrole. Om het praktischer te maken heb ik voorbeeldcode voorbereid om mee te spelen. Ik adviseer het klonen van deze repo om verder te gaan met het artikel gemakkelijker te maken. Het is maar één dossier. Als u eerst aan de oplossing wilt denken, wacht dan met het uitvoeren van de code.

Hier is de voorbeeldcode:

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?

u kunt de basisklasseRegionhier zien samen met twee dochterklassen: Country en CityCity en Country erven van Region. Erfenis wordt gebruikt om de openbare, particuliere en beschermde gegevens aan te tonen. Aan het einde van het bestand, kunnen we initialisatie deel en 4 secties die we hieronder zullen bespreken vinden. Bekijk het bestand om vertrouwd te raken met de code.

Ok, laten we beginnen! In de derde sectie van de initialisatie worden de volgende objecten aangemaakt: wroclawsan_francisco en poland. Deze objecten zullen worden gebruikt voor demonstratie doeleinden in de komende secties. Ik stel voor al deze segmenten afzonderlijk te behandelen. U kunt commentaar geven op de specifieke sectie voordat u naar de volgende. Op die manier zullen fouten de rest van de uitvoer niet blokkeren.

I sectie

onderwerp: publieke toegang.

in de eerste sectie wordt greeting methode tweemaal aangeroepen: door de wroclaw en door de poland objecten. Niets bijzonders hier. Openbare toegang is eenvoudig. greeting is toegankelijk voor het object van zijn klasse (poland) en voor het object van zijn dochterklasse (wroclaw).

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

conclusie: publieke toegang is evident en intuïtief. Er zijn geen beperkingen. Ook, het is de standaard toegang modifier.

II sectie

onderwerp: toegang tot de private en beschermde methoden van buiten de definiërende klasse.

Er zijn twee belangrijke methoden in die sectie: protected name_info en private population_info. Het resultaat lijkt weer intuïtief. wroclaw object heeft geen toegang tot noch de private methoden, noch de beschermde. In beide gevallen wordt NoMethodError gegooid.

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

conclusie: particuliere en beschermde methoden kunnen niet worden aangeroepen van buiten de klasse. Toegang is beperkt.

III sectie

onderwerp: toegang tot private en beschermde methoden vanuit de binnenkant van de definiërende klasse.

Deze keer hebben we City::own_greeting die overgeërfde beveiligde methode gebruikt binnen (name_info) en Country::own_greeting die overgeërfde privémethode gebruikt binnen (population_info). Zowel private als beschermde methoden (zelfs als ze worden overgeërfd) zijn toegankelijk binnen de klasse. Dus het is niet het punt dat private onderscheidt van beschermde toegang.

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

conclusie: Private en beschermde methoden kunnen worden aangeroepen vanuit de binnenkant van de definiërende klasse. Toegang is toegestaan.

IV sectie

onderwerp: feitelijk verschil tussen particuliere en beschermde methoden.

IV sectie – Meer onverwachte regels kunnen hier beginnen te verschijnen.U kunt hier 3 openbare methoden zien:

  • – het gebruikt private population_density binnenin.
  • the_same_continent?(other_region) – het gebruikt protected continent binnen.
  • can_be_crowdy? – het gebruikt private consider_as_densely_populated? binnen.

laten we de code stap voor stap doorlopen:

more_densely_populated?(other_region)

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

Hmm, dat is interessant. Private methode Region::population_density is niet aangeroepen, ook al is het geïmplementeerd in de Region klasse. Het soortgelijke scenario is uitgewerkt in de III sectie…

the_same_continent?(other_region)

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

Deze werkt. Enig verschil hier? Juist, the_same_continent? gebruikt beschermd attribuut – continent. Oké, laten we doorgaan.

can_be_crowdy?

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

NoMethodError opnieuw. Hmm, can_be_crowdy? gebruikt ook private consider_as_densely_populated? methode. Soortgelijke situatie Werkte prima in de afdeling III. Wat is hier aan de hand?

Het draait allemaal om de ontvanger.

in principe is de ontvanger het object waarvan de methode wordt aangeroepen. Laten we meteen naar de voorbeelden gaan:

  • other_region.population_density ? – de ontvanger is other_region.
  • other_region.continent – de ontvanger is other_region.
  • self.consider_as_densely_populated? – de ontvanger is self.

en hier is het belangrijke materiaal, onthoud die regel:

Private methoden kunnen niet worden aangeroepen met een expliciete ontvanger.

let hier op het woord ‘expliciet’. Vereenvoudiging van deze instructie-u kunt geen privé methode aanroepen door de aanroep als volgt te schrijven – object.some_method. U moet pure some_methodgebruiken. In het laatste geval gebruikt Ruby de impliciete ontvanger, die altijd selfis. Ongeacht dat feit, je kunt een privé methode nog steeds niet aanroepen met self.some_method, omdat het nog steeds een expliciete ontvanger is, en regels zijn regels:)

:

  • other_region.population_density ? – De expliciete ontvanger aanwezig is en de methode is privé – NoMethodError
  • other_region.continent – De expliciete ontvanger is aanwezig en het attribuut protected – OK
  • self.consider_as_densely_populated? De expliciete ontvanger aanwezig is en de methode is privé – NoMethodError

Conclusie: Dit is het feitelijke onderscheid tussen private en protected. Private methoden kunnen niet worden aangeroepen met een expliciete ontvanger en beschermde kunnen worden aangeroepen. Op basis van mijn ervaring, worden beschermde methoden zelden gebruikt onder Ruby code regels, maar ze kunnen nuttig zijn bij het vergelijken van parameters, bijvoorbeeld, wanneer we de toegang tot het attribuut willen beperken, maar nog steeds willen gebruiken in de vergelijking methode.

Ik hoop dat de toegangscontrole regels nu veel duidelijker zijn. Ik moedig je aan om je handen vuil te maken met de code als je het niet al gedaan had. De theorie wordt vaak vergeten als het niet is bestendig.

uiteindelijk, zoals beloofd-antwoorden op de statements:

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

samenvatting

Ik heb dit artikel geschreven omdat het voor mij ook verrassend was hoe publieke, private en beveiligde toegang in Ruby werkt. De eenvoudigste dingen zijn het moeilijkst te begrijpen, of dat kunnen ze tenminste zijn. Ik hoop echt dat dit artikel was nuttig voor u. Of misschien was u zich bewust van de toegangsregels voordat u het Las. Deel uw gedachten in de reacties, Ik ben erg nieuwsgierig van hen. Je kunt ook naar de dokter kijken. U vindt al deze details daar 🙂

join

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.