Oc-windows.ru

IT Новости из мира ПК
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Php protected private

Область видимости

Область видимости свойства или метода может быть определена путем использования следующих ключевых слов в объявлении: public, protected или private. Доступ к свойствам и методам класса, объявленным как public (общедоступный), разрешен отовсюду. Модификатор protected (защищенный) разрешает доступ наследуемым и родительским классам. Модификатор private (закрытый) ограничивает область видимости так, что только класс, где объявлен сам элемент, имеет к нему доступ.

Область видимости свойства

Свойства класса должны быть определены через модификаторы public, private, или protected. Если же свойство определено с помощью var, то оно будет доступно как public свойство.

Пример #1 Объявление свойства класса

/**
* Определение MyClass
*/
class MyClass
<
public $public = ‘Общий’ ;
protected $protected = ‘Защищенный’ ;
private $private = ‘Закрытый’ ;

function printHello ()
<
echo $this -> public ;
echo $this -> protected ;
echo $this -> private ;
>
>

$obj = new MyClass ();
echo $obj -> public ; // Работает
echo $obj -> protected ; // Неисправимая ошибка
echo $obj -> private ; // Неисправимая ошибка
$obj -> printHello (); // Выводит Общий, Защищенный и Закрытый

/**
* Определение MyClass2
*/
class MyClass2 extends MyClass
<
// Мы можем переопределить public и protected методы, но не private
protected $protected = ‘Защищенный2’ ;

function printHello ()
<
echo $this -> public ;
echo $this -> protected ;
echo $this -> private ;
>
>

$obj2 = new MyClass2 ();
echo $obj2 -> public ; // Работает
echo $obj2 -> protected ; // Неисправимая ошибка
echo $obj2 -> private ; // Неопределен
$obj2 -> printHello (); // Выводит Общий, Защищенный2 и Неопределен

Замечание: Метод объявления переменной через ключевое слово var, принятый в PHP 4, до сих пор поддерживается в целях совместимости (как синоним ключевого слова public). В версиях PHP 5 ниже 5.1.3 такое использование выводит предупреждение E_STRICT .

Область видимости метода

Методы класса должны быть определены через модификаторы public, private, или protected. Методы, где определение модификатора отсутствует, определяются как public.

Пример #2 Объявление метода

// Объявление общедоступного метода
public function MyPublic ()

// Объявление защищенного метода
protected function MyProtected ()

// Объявление закрытого метода
private function MyPrivate ()

// Это общедоступный метод
function Foo ()
<
$this -> MyPublic ();
$this -> MyProtected ();
$this -> MyPrivate ();
>
>

$myclass = new MyClass ;
$myclass -> MyPublic (); // Работает
$myclass -> MyProtected (); // Неисправимая ошибка
$myclass -> MyPrivate (); // Неисправимая ошибка
$myclass -> Foo (); // Работает общий, защищенный и закрытый

/**
* Определение MyClass2
*/
class MyClass2 extends MyClass
<
// Это общедоступный метод
function Foo2 ()
<
$this -> MyPublic ();
$this -> MyProtected ();
$this -> MyPrivate (); // Неисправимая ошибка
>
>

$myclass2 = new MyClass2 ;
$myclass2 -> MyPublic (); // Работает
$myclass2 -> Foo2 (); // Работает общий и защищенный, закрытый не работает

class Bar
<
public function test () <
$this -> testPrivate ();
$this -> testPublic ();
>

public function testPublic () <
echo «Bar::testPublicn» ;
>

private function testPrivate () <
echo «Bar::testPrivaten» ;
>
>

class Foo extends Bar
<
public function testPublic () <
echo «Foo::testPublicn» ;
>

private function testPrivate () <
echo «Foo::testPrivaten» ;
>
>

$myFoo = new foo ();
$myFoo -> test (); // Bar::testPrivate
// Foo::testPublic
?>

Видимость из других объектов

Объекты одного типа имеют доступ к элементам с модификаторами private и protected друг друга, даже если не являются одним и тем же экземпляром. Это объясняется тем, что реализация видимости элементов известна внутри этих объектов.

Пример #3 Доступ к элементам с модификатором private из объектов одного типа

class Test
<
private $foo ;

public function __construct ( $foo )
<
$this -> foo = $foo ;
>

private function bar ()
<
echo ‘Доступ к закрытому методу.’ ;
>

public function baz ( Test $other )
<
// Мы можем изменить закрытое свойство:
$other -> foo = ‘hello’ ;
var_dump ( $other -> foo );

// Мы также можем вызвать закрытый метод:
$other -> bar ();
>
>

$test = new Test ( ‘test’ );

$test -> baz (new Test ( ‘other’ ));
?>

Php protected private

INSIDE CODE and OUTSIDE CODE

class Item
<
/**
* This is INSIDE CODE because it is written INSIDE the class.
*/
public $label ;
public $price ;
>

/**
* This is OUTSIDE CODE because it is written OUTSIDE the class.
*/
$item = new Item ();
$item -> label = ‘Ink-Jet Tatoo Gun’ ;
$item -> price = 49.99 ;

?>

Ok, that’s simple enough. I got it inside and out. The big problem with this is that the Item class is COMPLETELY IGNORANT in the following ways:
* It REQUIRES OUTSIDE CODE to do all the work AND to know what and how to do it — huge mistake.
* OUTSIDE CODE can cast Item properties to any other PHP types (booleans, integers, floats, strings, arrays, and objects etc.) — another huge mistake.

Note: we did it correctly above, but what if someone made an array for $price? FYI: PHP has no clue what we mean by an Item, especially by the terms of our class definition above. To PHP, our Item is something with two properties (mutable in every way) and that’s it. As far as PHP is concerned, we can pack the entire set of Britannica Encyclopedias into the price slot. When that happens, we no longer have what we expect an Item to be.

Читать еще:  Php menuid guardant register

INSIDE CODE should keep the integrity of the object. For example, our class definition should keep $label a string and $price a float — which means only strings can come IN and OUT of the class for label, and only floats can come IN and OUT of the class for price.

class Item
<
/**
* Here’s the new INSIDE CODE and the Rules to follow:
*
* 1. STOP ACCESS to properties via $item->label and $item->price,
* by using the protected keyword.
* 2. FORCE the use of public functions.
* 3. ONLY strings are allowed IN & OUT of this class for $label
* via the getLabel and setLabel functions.
* 4. ONLY floats are allowed IN & OUT of this class for $price
* via the getPrice and setPrice functions.
*/

protected $label = ‘Unknown Item’ ; // Rule 1 — protected.
protected $price = 0.0 ; // Rule 1 — protected.

public function getLabel () < // Rule 2 - public function.
return $this -> label ; // Rule 3 — string OUT for $label.
>

public function getPrice () < // Rule 2 - public function.
return $this -> price ; // Rule 4 — float OUT for $price.
>

public function setLabel ( $label ) // Rule 2 — public function.
<
/**
* Make sure $label is a PHP string that can be used in a SORTING
* alogorithm, NOT a boolean, number, array, or object that can’t
* properly sort — AND to make sure that the getLabel() function
* ALWAYS returns a genuine PHP string.
*
* Using a RegExp would improve this function, however, the main
* point is the one made above.
*/

if( is_string ( $label ))
<
$this -> label = (string) $label ; // Rule 3 — string IN for $label.
>
>

public function setPrice ( $price ) // Rule 2 — public function.
<
/**
* Make sure $price is a PHP float so that it can be used in a
* NUMERICAL CALCULATION. Do not accept boolean, string, array or
* some other object that can’t be included in a simple calculation.
* This will ensure that the getPrice() function ALWAYS returns an
* authentic, genuine, full-flavored PHP number and nothing but.
*
* Checking for positive values may improve this function,
* however, the main point is the one made above.
*/

if( is_numeric ( $price ))
<
$this -> price = (float) $price ; // Rule 4 — float IN for $price.
>
>
>

?>

Now there is nothing OUTSIDE CODE can do to obscure the INSIDES of an Item. In other words, every instance of Item will always look and behave like any other Item complete with a label and a price, AND you can group them together and they will interact without disruption. Even though there is room for improvement, the basics are there, and PHP will not hassle you. which means you can keep your hair!

If you have problems with overriding private methods in extended classes, read this:)

The manual says that «Private limits visibility only to the class that defines the item». That means extended children classes do not see the private methods of parent class and vice versa also.

As a result, parents and children can have different implementations of the «same» private methods, depending on where you call them (e.g. parent or child class instance). Why? Because private methods are visible only for the class that defines them and the child class does not see the parent’s private methods. If the child doesn’t see the parent’s private methods, the child can’t override them. Scopes are different. In other words — each class has a private set of private variables that no-one else has access to.

A sample demonstrating the percularities of private methods when extending classes:

abstract class base <
public function inherited () <
$this -> overridden ();
>
private function overridden () <
echo ‘base’ ;
>
>

class child extends base <
private function overridden () <
echo ‘child’ ;
>
>

$test = new child ();
$test -> inherited ();
?>

Output will be «base».

If you want the inherited methods to use overridden functionality in extended classes but public sounds too loose, use protected. That’s what it is for:)

A sample that works as intended:

abstract class base <
public function inherited () <
$this -> overridden ();
>
protected function overridden () <
echo ‘base’ ;
>
>

class child extends base <
protected function overridden () <
echo ‘child’ ;
>
>

$test = new child ();
$test -> inherited ();
?>
Output will be «child».

PHP: Наследование

Наследование

Наследование — это механизм объектно ориентированного программирования, который позволяет описать новый класс на основе уже существующего (родительского).

Класс, который получается в результате наследования от другого, называется подклассом. Эту связь обычно описывают с помощью терминов «родительский» и «дочерний». Дочерний класс происходит от родительского и наследует его характеристики: свойства и методы. Обычно в подклассе к функциональности родительского класса (который также называют суперклассом) добавляются новые функциональные возможности.

Читать еще:  Как защитить отдельные ячейки

Чтобы создать подкласс, необходимо использовать в объявлении класса ключевое слово extends , и после него указать имя класса, от которого выполняется наследование:

Подкласс наследует доступ ко всем методам и свойствам родительского класса, так как они имеют тип public . Это означает, что для экземпляров класса my_Cat мы можем вызывать метод add_age() и обращаться к свойству $age не смотря на то, что они определены в классе cat . Также в приведенном примере подкласс не имеет своего конструктора. Если в подклассе не объявлен свой конструктор, то при создании экземпляров подкласса будет автоматически вызываться конструктор суперкласса.

Обратите внимание на то, что в подклассах могут переопределяться свойства и методы. Определяя подкласс, мы гарантируем, что его экземпляр определяется характеристиками сначала дочернего, а затем родительского класса. Чтобы лучше это понять рассмотрим пример:

При вызове $kitty->foo() интерпретатор PHP не может найти такой метод в классе my_Cat , поэтому используется реализация этого метода заданная в классе Cat . Однако в подклассе определено собственное свойство $age , поэтому при обращении к нему в методе $kitty->foo() , интерпретатор PHP находит это свойство в классе my_Cat и использует его.

Так как мы уже рассмотрели тему про указание типа аргументов, осталось сказать о том, что если в качестве типа указан родительский класс, то все потомки для метода будут так же доступны для использования, посмотрите на следующий пример:

Мы можем обращаться с экземпляром класса my_Cat так, как будто это объект типа Cat , т.е. мы можем передать объект типа my_Cat методу foo() класса Cat , и все будет работать, как надо.

Оператор parent

На практике подклассам бывает необходимо расширить функциональность методов родительского класса. Расширяя функциональность за счет переопределения методов суперкласса, в подклассах вы сохраняете возможность сначала выполнить программный код родительского класса, а затем добавить код, который реализует дополнительную функциональность. Давайте разберем как это можно сделать.

Чтобы вызвать нужный метод из родительского класса, вам понадобится обратиться к самому этому классу через дескриптор. Для этой цели в PHP предусмотрено ключевое слово parent . Оператор parent позволяет подклассам обращаться к методам (и конструкторам) родительского класса и дополнять их существующую функциональность. Чтобы обратиться к методу в контексте класса, используются символы » :: » (два двоеточия). Синтаксис оператора parent :

Эта конструкция вызовет метод, определенный в суперклассе. Вслед за таким вызовом можно поместить свой программный код, который добавит новую функциональность:

Когда в дочернем классе определяется свой конструктор, PHP не вызывает конструктор родительского класса автоматически. Это необходимо сделать вручную в конструкторе подкласса. Подкласс сначала в своем конструкторе вызывает конструктор своего родительского класса, передавая нужные аргументы для инициализации, исполняет его, а затем выполняется код, который реализует дополнительную функциональность, в данном случае инициализирует свойство подкласса.

Ключевое слово parent можно использовать не только в конструкторах, но и в любом другом методе, функциональность которого вы хотите расширить, достигнуть этого можно, вызвав метод родительского класса:

Здесь сначала вызывается метод getstr() из суперкласса, значение которого присваивается переменной, а после этого выполняется остальной код определенный в методе подкласса.

Теперь, когда мы познакомились с основами наследования, можно, наконец, рассмотреть вопрос видимости свойств и методов.

public, protected и private: управление доступом

До этого момента мы явно объявляли все свойства как public (общедоступные). И такой тип доступа задан по умолчанию для всех методов.

Элементы класса можно объявлять как public (общедоступные), protected (защищенные) и private (закрытые). Рассмотрим разницу между ними:

  • К public (общедоступным) свойствам и методам, можно получить доступ из любого контекста.
  • К protected (защищенным) свойствам и методам можно получить доступ либо из содержащего их класса, либо из его подкласса. Никакому внешнему коду доступ к ним не предоставляется.
  • Вы можете сделать данные класса недоступными для вызывающей программы с помощью ключевого слова private (закрытые). К таким свойствам и методам можно получить доступ только из того класса, в котором они объявлены. Даже подклассы данного класса не имеют доступа к таким данным.

public — открытый доступ:

private — доступ только из методов класса:

protected — защищенный доступ:

Модификатор protected с точки зрения вызывающей программы выглядит точно так же, как и private : он запрещает доступ к данным объекта извне. Однако в отличие от private он позволяет обращаться к данным не только из методов своего класса, но также и из методов подкласса.

What is the difference between public, private, and protected?

When and why should I use public , private , and protected functions and variables inside a class? What is the difference between them?

17 Answers 17

public scope to make that property/method available from anywhere, other classes and instances of the object.

private scope when you want your property/method to be visible in its own class only.

protected scope when you want to make your property/method visible in all classes that extend current class including the parent class.

Читать еще:  Multipart form data php

More: (For comprehensive information)

Public:

When you declare a method (function) or a property (variable) as public , those methods and properties can be accessed by:

  • The same class that declared it.
  • The classes that inherit the above declared class.
  • Any foreign elements outside this class can also access those things.

Example:

Protected:

When you declare a method (function) or a property (variable) as protected , those methods and properties can be accessed by

  • The same class that declared it.
  • The classes that inherit the above declared class.

Outsider members cannot access those variables. «Outsiders» in the sense that they are not object instances of the declared class itself.

Example:

The exact error will be this:

PHP Fatal error: Cannot access protected property GrandPa::$name

Private:

When you declare a method (function) or a property (variable) as private , those methods and properties can be accessed by:

  • The same class that declared it.

Outsider members cannot access those variables. Outsiders in the sense that they are not object instances of the declared class itself and even the classes that inherit the declared class.

Example:

The exact error messages will be:

Notice: Undefined property: Daddy::$name
Fatal error: Cannot access private property GrandPa::$name

Dissecting the Grandpa Class using Reflection

This subject is not really out of scope, and I’m adding it here just to prove that reflection is really powerful. As I had stated in the above three examples, protected and private members (properties and methods) cannot be accessed outside of the class.

However, with reflection you can do the extra-ordinary by even accessing protected and private members outside of the class!

Well, what is reflection?

Reflection adds the ability to reverse-engineer classes, interfaces, functions, methods and extensions. Additionally, they offers ways to retrieve doc comments for functions, classes and methods.

Preamble

We have a class named Grandpas and say we have three properties. For easy understanding, consider there are three grandpas with names:

Let us make them (assign modifiers) public , protected and private respectively. You know very well that protected and private members cannot be accessed outside the class. Now let’s contradict the statement using reflection.

The code

Output:

Common Misconceptions:

Please do not confuse with the below example. As you can still see, the private and protected members cannot be accessed outside of the class without using reflection

Output:

Debugging functions

print_r , var_export and var_dump are debugger functions. They present information about a variable in a human-readable form. These three functions will reveal the protected and private properties of objects with PHP 5. Static class members will not be shown.

More resources:

It is typically considered good practice to default to the lowest visibility required as this promotes data encapsulation and good interface design. When considering member variable and method visibility think about the role the member plays in the interaction with other objects.

If you «code to an interface rather than implementation» then it’s usually pretty straightforward to make visibility decisions. In general, variables should be private or protected unless you have a good reason to expose them. Use public accessors (getters/setters) instead to limit and regulate access to a class’s internals.

To use a car as an analogy, things like speed, gear, and direction would be private instance variables. You don’t want the driver to directly manipulate things like air/fuel ratio. Instead, you expose a limited number of actions as public methods. The interface to a car might include methods such as accelerate() , deccelerate() / brake() , setGear() , turnLeft() , turnRight() , etc.

The driver doesn’t know nor should he care how these actions are implemented by the car’s internals, and exposing that functionality could be dangerous to the driver and others on the road. Hence the good practice of designing a public interface and encapsulating the data behind that interface.

This approach also allows you to alter and improve the implementation of the public methods in your class without breaking the interface’s contract with client code. For example, you could improve the accelerate() method to be more fuel efficient, yet the usage of that method would remain the same; client code would require no changes but still reap the benefits of your efficiency improvement.

Edit: Since it seems you are still in the midst of learning object oriented concepts (which are much more difficult to master than any language’s syntax), I highly recommend picking up a copy of PHP Objects, Patterns, and Practice by Matt Zandstra. This is the book that first taught me how to use OOP effectively, rather than just teaching me the syntax. I had learned the syntax years beforehand, but that was useless without understanding the «why» of OOP.

Ссылка на основную публикацию
Adblock
detector