Статьи

Признания преобразованного разработчика PHP: о видимости и правах

Хорошо, класс — сегодня я здесь, чтобы поговорить о различиях и сходствах, которые есть у PHP и Ruby, когда речь идет о свойствах объектов, методах и их видимости, о том, как вы создаете переменные внутри классов и как вы можете взаимодействовать с ними.

Краткий обзор того, что мы знаем

В PHP свойства объекта могут быть установлены на одно из трех значений; public , protected и private . Свойства, которые не имеют декларации видимости, по умолчанию являются открытыми. Каждое из этих объявлений изменяет информацию, доступную для самого класса, его родительских и дочерних объектов и другого кода, взаимодействующего с ним. Давайте вспомним, как они работают быстро.

  • Публичные переменные доступны везде
  • Защищенные переменные доступны только внутри класса и его родителей или детей
  • Закрытые переменные доступны только в классе, где они указаны, и недоступны для классов, которые расширяют их

Для обработки взаимодействий с защищенными и закрытыми свойствами обычно создаются методы доступа getter и setter. Это функции, которые позволяют вам устанавливать и извлекать значения свойств, и, как правило, все они выглядят примерно одинаково — если только они на самом деле не выполняют манипуляции с данными, которые хранятся, их обычно считают однострочными функциями, возвращающими или устанавливающими свойство :

 <?PHP &nbsp; class animal { private $_species; protected $_name; &nbsp; public function get_species() { return $this->_species; } &nbsp; public function get_name() { return $this->_name; } } &nbsp; class pterodactyl extends animal { public function __construct() { $this->_name = $name; $this->_species = 'dinosaur'; } } &nbsp; $my_big_birdie = new pterodactyl('Daryl'); &nbsp; var_dump($my_big_birdie->get_name()); // string(5) 'Daryl' var_dump($my_big_birdie->get_species()); // NULL 

Вызов метода get_name возвращает имя, которое мы установили, поскольку эта переменная была защищена и доступна в дочернем классе. Установив _species в дочернем классе, он создал новое открытое свойство с именем _species и оставил приватное свойство _species в родительском классе NULL. Полный дамп $my_big_birdie покажет нам это:

 Object(pterodactyl)#1 (3) { ["_species":"animal":private]=> NULL ["_name":protected]=> string(5) "Daryl" ["_species"]=> string(8) "dinosaur" } 

У Ruby точно нет свойств, как мы о них думаем. Вместо этого вы должны определить методы получения и установки для любых переменных экземпляра, к которым вы хотите получить доступ. Их обычно называют читателями и писателями. (Переменные с символом @ перед ними являются переменными экземпляра, что означает, что они доступны внутри области видимости класса.)

 class Animal def initialize(name) @name = name end &nbsp; def name @name end &nbsp; def name=(name) @name = name end &nbsp; def species @species end end 

В этом примере мы реализовали класс животных из PHP в Ruby. Обратите внимание, что метод определения определяется простым добавлением равенства в конец имени метода.

Поскольку написание методов получения и установки может быть повторяющимся процессом, Ruby упрощает это, позволяя нам объявлять переменные экземпляра, которые мы хотим использовать в качестве атрибутов:

 class Animal attr_reader :species attr_accessor :name &nbsp; def initialize(name) @name = name end end 

Теперь у нас тот же класс, что и раньше, за исключением того, что мы создаем наши attr_reader получения и установки с помощью Ruby attr_reader и attr_accessor . attr_reader создает только метод получения, attr_writer (здесь не используется) только метод установки, а attr_accessor создает оба метода. В 90% случаев это все, что нам нужно сделать, чтобы представить наши переменные в качестве атрибутов, и в тех случаях, когда вам требуется больше функциональности, вы можете просто использовать стандартную конструкцию метода.

В Ruby также есть разные реализации Public, Private и Protected. По умолчанию все методы являются public , но вы можете объявить видимость, сделав один protected или private оператор, и тогда у всех последующих методов будет такая видимость. Это позволяет группировать методы с одинаковой видимостью:

 class MyClass # the default visibility is public def my_public_method end &nbsp; protected def my_protected_method end &nbsp; def my_other_protected_method end &nbsp; private def my_private_method end end 

Реализация защищенных и закрытых в Ruby сильно отличается от реализации в PHP и не имеет ничего общего с наследованием объектов. Private в Ruby больше похож на Protected в PHP. Закрытый метод в Ruby может быть доступен внутри контекста объекта или любого унаследованного объекта.

 class Foo private def bar puts "bar called" end end &nbsp; class Blarg < Foo def initialize bar end end 

Поскольку класс Blarg расширяет Foo , он может вызывать приватный метод bar.

Реализация защищенного в Ruby полностью отличается от чего-либо в PHP. Защищенные методы могут быть вызваны любым объектом того же класса:

 class Person attr_writer :mother &nbsp; def initialize(name) @name = name end &nbsp; def mother_name @mother.name if end &nbsp; protected def name @name end end &nbsp; me = Person.new('Mal') mum = Person.new('Jeni') &nbsp; me.mother = mum &nbsp; puts me.mother_name # => Jeni puts me.name # => NoMethodError: protected method `name' called for # 

Здесь у нас есть класс person, который разрешает защищенный доступ только к имени. Когда я создаю два экземпляра и устанавливаю атрибут mother одного экземпляра для другого экземпляра, то метод mother_name способен вызывать атрибут name материнской переменной, однако я не могу вызвать атрибут name вне области действия самого объекта. ,

Это был краткий обзор некоторых фундаментальных различий между PHP и свойствами классов Ruby и видимостью методов — можете ли вы вспомнить какие-либо другие основные отличия, о которых стоит упомянуть?