@sprashivatel

Вызов метода родителя по имени потомка — это self или static?

В родителе protected static метод, например test().
Если я в потомке вызываю этот метод Потомок::test(), то это self::test() или static::test()?

class A
{
  protected static function test()
  {
    echo self::$test;
  }
}

class B extends A
{
  public static function testFoTest()
  {
    B::test(); // это self::test() или static::test() ?
  }
}
  • Вопрос задан
  • 123 просмотра
Решения вопроса 1
VicTHOR
@VicTHOR
(╮°-°)╮┳━━┳ ( ╯°□°)╯ ┻━━┻
Если вызывать self и static из дочернего класса, то будет вызван дочерний класс в любом случае.
Разницу видно при вызове из родителя. По умолчанию родитель ничего не знает о наследниках, но благодаря static может вызывать их переопределенные методы, а не свои.
А что-бы дочернему классу указать вызов родителя, используется parent
sandbox
code
class A
{
    public static function test()
    {
        echo 'class A';
    }
    
    public static function testMethodFromParent()
    {
        echo self::test()." | self::test()\n";
        echo static::test()." | static::test()\n";
        echo B::test()." | B::test()\n";
    }
}

class B extends A
{
    
    public static function test()
    {
        echo 'class B';
    }
    
    public static function testMethodFromChild()
    {
        echo B::test()." | B::test()\n";
        echo self::test()." | self::test()\n";
        echo static::test()." | static::test()\n";
        echo parent::test()." | parent::test()\n";
    }
    
}

echo "Вызов функции дочернего класса в дочернем классе\n";
B::testMethodFromChild();
echo "\nВызов родительской функции в дочернем классе\n";
B::testMethodFromParent();

/*
Вызов функции дочернего класса в дочернем классе
class B | B::test()
class B | self::test()
class B | static::test()
class A | parent::test()

Вызов родительской функции в дочернем классе
class A | self::test()
class B | static::test()
class B | B::test()
*/
И вот здесь уже видно, что B::test() - то же, что и static::test(), но привязано к B, а не к тому дочернему классу, который вызывает метод, в отличие от static.
А при вызове из потомка self совпадает со static, и в целом каждая запись имеет свои особенности.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Oegir
@Oegir
Web-программист
В таком контексте без разницы. Пример:
class p
{
    protected static function parentFunc()
    {
        echo 'Hello from parent<br>';
    }
}

class ch extends p
{
    public static function chilStatic()
    {
        static::parentFunc();
    }
    
    public static function childParent()
    {
        parent::parentFunc();
    }
}

ch::chilStatic();
ch::childParent();

Выведет:
Hello from parent
Hello from parent

Но если так:
class p
{
    protected static function parentFunc()
    {
        echo 'Hello from parent<br>';
    }
}

class ch extends p
{
    protected static function parentFunc()
    {
        echo 'Hello from child<br>';
    }
    
    public static function chilStatic()
    {
        static::parentFunc();
    }
    
    public static function childParent()
    {
        parent::parentFunc();
    }
}

ch::chilStatic();
ch::childParent();

Выведет:
Hello from child
Hello from parent
Ответ написан
syamskoy
@syamskoy
Вам поможет оф.документация по раннему и позднему статическому связыванию: https://www.php.net/manual/ru/language.oop5.late-s... self и static выбираются в зависимости от того, что требуется в конечном итоге.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы