In die Zwischenablage kopieren

TwitterFacebook

Öffentlicher, privater und geschützter Zugriff – alle Programmierer sind mit diesem Konzept vertraut. Nichts Besonderes, wir arbeiten täglich mit ihnen zusammen. Aber kennen wir als Ruby-Programmierer wirklich die Details?

Sie können sich mit diesen fünf Aussagen überprüfen. Versuchen Sie zu antworten: WAHR oder FALSCH.

Anweisungen:

  1. Öffentliche Methoden haben keine Zugriffskontrolle – sie können von außerhalb der Klassendefinition von der Instanz dieser Klasse oder ihren Unterklassen aufgerufen werden.
  2. Sowohl geschützte als auch private Methoden können nicht von außerhalb der definierenden Klasse aufgerufen werden.
  3. Geschützte Methoden sind von der Unterklasse aus zugänglich und private Methoden nicht.
  4. Private Methoden der definierenden Klasse können von jeder Instanz dieser Klasse aufgerufen werden.
  5. Öffentlicher Zugriff ist der Standardzugriff.

Wir werden am Ende dieses Artikels auf die richtigen Antworten zurückkommen. Lassen Sie uns zunächst einige Nuancen der öffentlichen, privaten und geschützten Zugriffskontrolle genauer untersuchen. Um es praktischer zu machen, habe ich Beispielcode zum Spielen vorbereitet. Ich empfehle, dieses Repo zu klonen, um die Fortsetzung des Artikels zu erleichtern. Es ist nur eine Datei. Wenn Sie zuerst an die Lösung denken möchten, halten Sie den Code aus.

Hier ist der Beispielcode:

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?

Sie können die Basisklasse Region hier zusammen mit zwei untergeordneten Klassen sehen: Country und CityCity und Country erben von Region. Vererbung wird verwendet, um die öffentlichen, privaten und geschützten Details zu demonstrieren. Am Ende der Datei finden wir den Initialisierungsteil und 4 Abschnitte, die wir unten besprechen werden. Schauen Sie sich die Datei an, um sich mit dem Code vertraut zu machen.

Ok, fangen wir an! Im 3. Abschnitt der Initialisierung werden die folgenden Objekte erstellt – wroclawsan_francisco und poland. Diese Objekte werden in den kommenden Abschnitten zu Demonstrationszwecken verwendet. Ich schlage vor, alle diese Segmente getrennt zu behandeln. Sie können den jeweiligen Abschnitt auskommentieren, bevor Sie zum nächsten gehen. Auf diese Weise blockieren Fehler den Rest der Ausgabe nicht.

I Abschnitt

Thema: Öffentlicher Zugang.

Im ersten Abschnitt greeting Methode wird zweimal aufgerufen: durch die wroclaw und durch die poland Objekte. Nichts Besonderes hier. Der öffentliche Zugang ist unkompliziert. Das greeting ist für das Objekt seiner Klasse (poland) und für das Objekt seiner untergeordneten Klasse (wroclaw) zugänglich.

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

Fazit: Der öffentliche Zugang ist offensichtlich und intuitiv. Es gibt keine Einschränkungen. Außerdem ist es der Standardzugriffsmodifikator.

II Abschnitt

Thema: Zugriff auf die privaten und geschützten Methoden von außerhalb der definierenden Klasse.

In diesem Abschnitt gibt es zwei wichtige Methoden: protected name_info und private population_info. Das Ergebnis scheint wieder intuitiv zu sein. wroclaw Das Objekt hat weder Zugriff auf die privaten noch auf die geschützten Methoden. In beiden Fällen wird NoMethodError geworfen.

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

Fazit: Private und geschützte Methoden können nicht von außerhalb der Klasse aufgerufen werden. Der Zugang ist eingeschränkt.

III Abschnitt

Thema: Zugriff auf private und geschützte Methoden aus dem Inneren der definierenden Klasse.

Dieses Mal haben wir City::own_greeting die geerbte geschützte Methode im Inneren verwendet (name_info) und Country::own_greeting die geerbte private Methode im Inneren verwendet (population_info). Sowohl private als auch geschützte Methoden (auch wenn sie vererbt werden) sind innerhalb der Klasse zugänglich. Es ist also nicht der Punkt, der den privaten vom geschützten Zugang unterscheidet.

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

Fazit: Private und geschützte Methoden können innerhalb der definierenden Klasse aufgerufen werden. Der Zugang ist erlaubt.

IV Abschnitt

Thema: Tatsächlicher Unterschied zwischen privaten und geschützten Methoden.

IV Abschnitt – Weitere unerwartete Regeln können hier erscheinen.Sie können dort 3 öffentliche Methoden sehen:

  • more_densely_populated?(other_region) – es verwendet private population_density innen.
  • the_same_continent?(other_region) – es verwendet geschützte continent innen.
  • can_be_crowdy? – es verwendet private consider_as_densely_populated? im Inneren.

Gehen wir den Code Schritt für Schritt durch:

more_densely_populated?(other_region)

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

Hmm, das ist interessant. Die private Methode Region::population_density wurde nicht aufgerufen, obwohl sie in der Klasse Region implementiert ist. Das ähnliche Szenario wurde im dritten Abschnitt bearbeitet …

the_same_continent?(other_region)

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

Dieser funktioniert. Irgendeinen Unterschied hier? Richtig, the_same_continent? verwendet das geschützte Attribut – continent. OK, lass uns weitermachen.

can_be_crowdy?

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

NoMethodError wieder. Hmm, can_be_crowdy? verwendet auch die private consider_as_densely_populated? Methode. Ähnliche Situation funktionierte gut in der III Abschnitt. Also, was ist hier los?

Es geht um den Empfänger.

Grundsätzlich ist der Empfänger das Objekt, dessen Methode aufgerufen wird. Gehen wir direkt zu den Beispielen:

  • other_region.population_density ? – Der Empfänger ist other_region.
  • other_region.continent – Der Empfänger ist other_region.
  • self.consider_as_densely_populated? – Der Empfänger ist self.

Und hier ist das Wichtige, erinnere dich an diese Regel:

Private Methoden können nicht mit einem expliziten Empfänger aufgerufen werden.

Achten Sie hier auf das Wort „explizit“. Vereinfachung dieser Anweisung – Sie können die private Methode nicht aufrufen, indem Sie den Aufruf wie folgt schreiben – object.some_method . Sie müssen pure some_method . Im letzteren Fall verwendet Ruby den impliziten Empfänger, der immer self . Unabhängig davon können Sie eine private Methode immer noch nicht mit self.some_method aufrufen, da es sich immer noch um einen expliziten Empfänger handelt und Regeln Regeln sind 🙂

Zurück zu unseren Methoden:

  • other_region.population_density ? – Der explizite Empfänger ist vorhanden und das Attribut ist privat – NoMethodError
  • other_region.continent – Der explizite Empfänger ist vorhanden und das Attribut ist geschützt – OK
  • self.consider_as_densely_populated? – Der explizite Empfänger ist vorhanden und die Methode ist privat – NoMethodError

Fazit: Dies ist die eigentliche Unterscheidung zwischen privat und geschützt. Private Methoden können nicht mit einem expliziten Empfänger aufgerufen werden, geschützte Methoden nicht. Aufgrund meiner Erfahrung werden geschützte Methoden selten in Ruby-Codezeilen verwendet, sie können jedoch beim Vergleichen von Parametern nützlich sein, z. B. wenn wir den Zugriff auf das Attribut einschränken, es aber dennoch in der Vergleichsmethode verwenden möchten.

Ich hoffe, dass die Zugriffskontrollregeln jetzt viel klarer sind. Ich ermutige Sie, sich mit dem Code die Hände schmutzig zu machen, wenn Sie es noch nicht getan haben. Theorie neigt dazu, vergessen zu werden, wenn sie nicht bewiesen wird.

Am Ende, wie versprochen – Antworten auf die Aussagen:

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

Zusammenfassung

Ich habe diesen Artikel geschrieben, weil es für mich auch überraschend war, wie öffentlicher, privater und geschützter Zugriff in Ruby tatsächlich funktionieren. Die einfachsten Dinge sind am schwersten zu verstehen, oder zumindest können sie es sein. Ich hoffe wirklich, dass dieser Artikel für Sie hilfreich war. Oder vielleicht waren Sie sich der Zugriffsregeln bewusst, bevor Sie sie gelesen haben. Teilen Sie Ihre Gedanken in den Kommentaren, ich bin sehr neugierig auf sie. Sie können sich auch die Dokumente ansehen. All diese Details finden Sie dort 🙂

beitreten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.