В объектах php, почему статические переменные могут быть доступны только с помощью :: notation, но статические методы могут быть вызваны из обоих :: & -> - PullRequest
0 голосов
/ 23 декабря 2018

В PHP, например, вы определяете переменную и метод static в классе.Для его объектов, почему мы можем обращаться только к переменным с помощью :: notation, тогда как мы можем запускать статические методы с -> или :: both?Почему это двойственное поведение?

class first {
    //variable
    public static $var=5;

    //method
    static function new(){
        echo "<br>";
        echo self::$var;
        echo "<br>";
    }
}

class second {

}

$obj = new first();

echo $obj->$var; // this throws an error
echo $obj::$var; // this runs
$obj->new(); // this also runs
$obj::new(); // this runs

1 Ответ

0 голосов
/ 23 декабря 2018

Несмотря на произвольность, статическая переменная класса принадлежит только классу, а не объекту.Метод статического класса принадлежит как классу, так и объекту этого класса.

Как показано ниже, изменение статической переменной класса приведет к изменению переменной во всех экземплярах этого класса.Таким образом, запись -> была бы обманчива.Этого не происходит с методом статического класса.

Представьте себе, что -> будет разрешено для статических переменных, тогда

вызов $ someObjectOfTypeX-> some_static_variable = 'some_value' изменит состояние $anotherObjectOfTypeX.

Однако вызов $ someObjectOfTypeX-> someStaticFunction () не меняет состояние $ anotherObjectOfTypeX.

Хотя ключевое слово static идентично, оно имеет различные значения для функций и переменных.Статические переменные являются общими для всех экземпляров класса.Статическая функция не изменяет состояние объектов и, следовательно, также не будет изменять состояние других экземпляров того же класса.

<?php

class first
{
    //variable
    public static $var = 5;

    //method
    static function new()
    {
        echo "<br>";
        echo self::$var;
        echo "<br>";
    }
}

$obj1 = new first();
$obj2 = new first();

echo $obj1->var; // this throws an error
echo $obj1::$var; // this runs
echo first::$var; // this runs

$obj2::$var = 10; // changes $var in class first (both object $obj1 and object $obj2)
$obj2->var = 15; // this throws an error (if it didn't it would change the variable also in $obj1)

$obj1->new(); // this also runs
$obj1::new(); // this runs
first::new(); // this runs
...