static:: HELP!

3jIo

Новичок
PHP:
function TestOPP() {
    class Test
    {
        static public function getNew()
        {
            return new static;
        }
    }

    class Child extends Test
    {}

    $obj1 = new Test();
    $obj2 = new $obj1;
    var_dump($obj1 !== $obj2);


    $obj3 = Test::getNew();
    var_dump($obj3 instanceof Test);
    echo "<br>", get_class($obj3);

    $obj4 = Child::getNew();
    var_dump($obj4 instanceof Child);
    echo "<br>", get_class($obj4);
}
Что тут происходит? Как это понимать: return new STATIC;
а это: $obj2 = new $obj1;
Так вообще стоит писать? Это считается нормальной практикой? И да где написано что static возвращает новый объект???
 

Вурдалак

Продвинутый новичок
LSB — говнокод и хак имени PHP, который почти не имеет отношения к OOP.
 

3jIo

Новичок
php.net/lsb

гы, забавно, не знал, что так работает :)
наверное, не надо.
Так там говориться позднем статическом связывание. То есть static работает как $this в статическом контексте или полностью как $this в контексте экземпляра.
То есть по сути полиморфизм только в статическом контексте. Но там не говорится что он возвращает новый объект. Самое интересно что можно написать так:
PHP:
static public function getNew()

        {
            return new self;
        }
И будет тот же результат. И да тут можно предположить что происходит тоже самое что и тут: $obj2 = new $obj1; ну или в self название класса содержится.
 

3jIo

Новичок
Вот ещё подводный камень:
Тут все окей:
PHP:
function TestStatic3()
{
    class AAA {
        private function foo() {
            echo "success!\n";
        }
        public function test() {
            $this->foo();
            static::foo();
        }
    }

    class BBB extends AAA {
        /* foo() будет скопирован в В, следовательно его область действия по прежнему А,
          и вызов будет успешен*/
    }

    class CCC extends AAA {
        private function foo() {
            /* исходный метод заменен; область действия нового метода С */
        }
    }

    $b = new BBB();
    $b->test();
}

TestStatic3();
А тут Fatal Error:
PHP:
function TestStatic3()
{
    class AAA {
        private function foo() {
            echo "success!\n";
        }
        public function test() {
            $this->foo();
            static::foo();
        }
    }

    class BBB extends AAA {
        /* foo() будет скопирован в В, следовательно его область действия по прежнему А,
          и вызов будет успешен*/

        private function foo() {
            echo "success22!\n";
        }
    }

    class CCC extends AAA {
        private function foo() {
            /* исходный метод заменен; область действия нового метода С */
        }
    }

    $b = new BBB();
    $b->test();
}

TestStatic3();
FACEPALM
 

fixxxer

К.О.
Партнер клуба
3jIo, с чего ты взял, что static что-то "возвращает"?

self резолвится в compile-time имя класса, static - в runtime-имя класса.

new self идентично $className = __CLASS__; new $className;
new static идентично $className = get_called_class(); new $className;
 

3jIo

Новичок
3jIo, с чего ты взял, что static что-то "возвращает"?

self резолвится в compile-time имя класса, static - в runtime-имя класса.

new self идентично $className = __CLASS__; new $className;
new static идентично $className = get_called_class(); new $className;
Скорей всего ,так и есть так как __CLASS__ содержит просто строку. а как знаем мы можем сделать даже так:
$someClass = "SomeClass";
new $someClass; Просто при вар_дампе или эхо не получается вывести static.
 

fixxxer

К.О.
Партнер клуба
разумеется, потому что это language construct. это так же бессмысленно, как пытаться вывести class или function
 

fixxxer

К.О.
Партнер клуба
Да какой конструктор копирования. Там что-то вроде

PHP:
if (is_object($className)) {
     $className = get_class($className);
}
Нафига такой тупак нужен, я не знаю :)
 

fixxxer

К.О.
Партнер клуба
Просто видимо общая логика с instanceof $object
Да, наверное.
LSB — говнокод и хак имени PHP, который почти не имеет отношения к OOP.
Ну, отсутствие constructor overloading обойти позволяет, хотя оно само по себе спорная вещь, да.
 
Сверху