За последние 24 часа нас посетили 21778 программистов и 1024 робота. Сейчас ищут 669 программистов ...

Переопределения статических свойств и вызов их в родительском классе

Тема в разделе "Вопросы от блондинок", создана пользователем Plush, 24 дек 2017.

  1. Plush

    Plush Новичок

    С нами с:
    24 дек 2017
    Сообщения:
    4
    Симпатии:
    0
    Здравствуйте.
    Помогите разобраться, почему интерпретатор выводит "white", когда должно быть по моей логике "black"?
    PHP:
    1. class Dog {
    2.   static public $color = "white";
    3.   public function getColor(){
    4.     return self::$color;
    5.   }
    6. }
    7.  
    8. class BigDog extends Dog{
    9.   static public $color = "black";
    10. }
    11.  
    12. $oBigDog = new BigDog();
    13. echo $oBigDog->getColor(); // white
    По моей логике:
    Метод getColor наследуется в классе BigDog и должен вызывать свойство "$color" класса BigDog, а не класса Dog.
    Почему происходит обращения к свойству color класса Dog?

    Спасибо, за внимание)
     
    #1 Plush, 24 дек 2017
    Последнее редактирование: 24 дек 2017
  2. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    попробуй не селф а статик и тогда позднее статическое связывание тебя обрадует ожидаемым результатом
     
  3. Plush

    Plush Новичок

    С нами с:
    24 дек 2017
    Сообщения:
    4
    Симпатии:
    0
    Ganzal, я так делал) И здесь работа кода мне понятна.
    PHP:
    1. class Dog {
    2.   static public $color = "white";
    3.   public function getColor(){
    4.     return static::$color;
    5.   }
    6. }
    7.  
    8. class BigDog extends Dog{
    9.   static public $color = "black";
    10. }
    11.  
    12. $oBigDog = new BigDog();
    13. echo $oBigDog->getColor(); // black
    и так делал))) И тут все логично.

    PHP:
    1. class Dog {
    2.   static public $color = "white";
    3.   public function getColor(){
    4.     return self::$color;
    5.   }
    6. }
    7.  
    8. class BigDog extends Dog{
    9.   static public $color = "black";
    10.   public function getColor(){
    11.     return self::$color;
    12.   }
    13. }
    14.  
    15. $oBigDog = new BigDog();
    16. echo $oBigDog->getColor(); // black
    Причем последний код, это копия должна быть первого.
    Но почему он так себя ведет, я не как не могу понять?
    --- Добавлено ---
    Это как? Можно чуть подробнее? Пожалуйста
     
    #3 Plush, 24 дек 2017
    Последнее редактирование: 24 дек 2017
  4. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    PHP:
    1. class A {
    2. public static $prop = 'aaa';
    3.  
    4. public function met()
    5. {
    6. var_dump(self::$prop, static::$prop);
    7. }
    8. }
    9.  
    10. class B extends A {
    11. public static $prop = 'bbb';
    12. }
    13.  
    14. $a = new A;
    15. $b = new B;
    16.  
    17. $a->met();
    18. $b->met();
    Код (Text):
    1.  
    2. string(3) "aaa"
    3.  
    4. string(3) "aaa"
    5.  
    6. string(3) "aaa"
    7.  
    8. string(3) "bbb"
    что я делаю не так?
     
    MouseZver нравится это.
  5. Plush

    Plush Новичок

    С нами с:
    24 дек 2017
    Сообщения:
    4
    Симпатии:
    0
    Ganzal, все норм)
    static работает по правилу: был наследован, бери свойства класса наследника. Тут вопросов нет. Все сходится с документацией по PHP.
    А вот self выводит всегда те свойства класса в котором он объявлен и пофиг, что он наследован в другом классе и в этом классе переопределены свойства.
    Почему наследование или переопределения не сработала для self, есть где-то документация, правило, такого поведения?
     
  6. Ganzal

    Ganzal Суперстар
    Команда форума Модератор

    С нами с:
    15 мар 2007
    Сообщения:
    9.902
    Симпатии:
    969
    @Plush да я-то в курсе как работает позднее статическое связывание. Сэлф всегда будет работать в том классе, где идет объявление, сколько бы потом класс не наследовался - каждый потомок будет всё равно использовать самое первое объявление. А статик работает именно в режиме лсб - когда вызывается класс (статически или создается его экземпляр) то вся ветка наследования читается сверху-вниз и будет использовано то объявление, которое встретилось позже всего.
    PHP:
    1. class A {
    2. public static $prop = 'aaa';
    3.  
    4. public function met()
    5. {
    6. var_dump(self::$prop, static::$prop);
    7. }
    8. }
    9.  
    10. class B extends A {
    11. public static $prop = 'bbb';
    12. }
    13.  
    14. class C extends B {}
    15.  
    16. class D extends C {
    17. public static $prop = 'ddd';
    18. }
    19.  
    20. $a = new A;
    21. $b = new B;
    22. $c = new C;
    23. $d = new D;
    24.  
    25.  
    26. $a->met();
    27. $b->met();
    28. $c->met();
    29. $d->met();
    Код (Text):
    1. string(3) "aaa"
    2. string(3) "aaa"
    3.  
    4. string(3) "aaa"
    5. string(3) "bbb"
    6.  
    7. string(3) "aaa"
    8. string(3) "bbb" <-- в классе Ц нет переопределения проп, поэтому лсб использует последнее переопределение - в Б
    9.  
    10. string(3) "aaa"
    11. string(3) "ddd" <-- а в классе Д опять есть переопределение, которое лсб и будет использовать как результирующее
    12.  
    13. а сэлф везде тот же самый так как изначально был объявлен именно в классе А
     
  7. Plush

    Plush Новичок

    С нами с:
    24 дек 2017
    Сообщения:
    4
    Симпатии:
    0
    Ganzal, понятно, спасибо.