За последние 24 часа нас посетили 54795 программистов и 1781 робот. Сейчас ищут 1636 программистов ...

Private конструктор

Тема в разделе "Прочие вопросы по PHP", создана пользователем Clickbeetle, 19 апр 2012.

  1. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    Возникла следующая ситуация:
    Есть какой-то класс (паттерн одиночка), у него есть private конструктор
    Код (Text):
    1.  
    2. class foo
    3. {
    4.    private function __construct()
    5.    {
    6.    ...
    7.    }
    8. }
    Естественно конструктор должен выполняться только один раз.
    Но если я потом от этого класса наследую другой класс (который не использует паттерн одиночка), у которого нет конструктора
    Код (Text):
    1.  
    2. class foo2 extends foo
    3. {
    4.    ...
    5. }
    То при создании объекта foo2 будет вызываться конструктор базового класса. Соотвественно если у foo2 есть свой конструктор, то нет. А нормально, что при отсутствии конструктора у дочернего класса то, что вызывается конструктор родительского класса, несмотря на то, что он private? Нигде не нашел на этот вопрос ответ. А мне собственно интересно) Заранее спасибо!
     
  2. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    хитрО...
     
  3. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    ))) Так я чего то недопонимаю или это так и должно быть?
     
  4. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    надо читать. так в голову ничего не приходит. наверняка гденить обсосано. по логике, должен быть эррор.
     
  5. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    Если сделать так, то error естественно будет
    Код (Text):
    1.  
    2. class foo2 extends foo
    3. {
    4.    public function __construct()
    5.    {
    6.       parent::__construct();
    7.    }
    8. }
    Но вот когда автоматом вызывается родительский конструктор, он почему-то проскакивает...

    Добавлено спустя 4 минуты 8 секунд:
    Разобрался) Забыл упомянуть, что объект класса foo2 создавался в одном из методов класса foo, поэтому для него private не имело значений)
     
  6. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    т.е. если нечто наследуется внутри родителя, то приватные и протектед методы ему доступны в самом себе? =)
     
  7. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    Ну получается видимо что так)
    Код (Text):
    1.  
    2. class foo
    3. {
    4.    private function __construct()
    5.    {
    6.    ...
    7.    }
    8.  
    9.    public function GetFoo2()
    10.    {
    11.       return new foo2;
    12.    }
    13. }
    Так как мы создаем объект внутри нашего класса, то все равно что обращаемся к своему же методу, хотя мне такое поведение не нравится))

    Добавлено спустя 1 минуту 7 секунд:
    Обошел это дополнительной проверкой внутри конструктора foo на наличие экземпляра foo(у нас ведь одиночка).
     
  8. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    я всегда считал, что если ты написал private, то независимо от места наследования, ничего не унаследуется.

    а с другими приватными методами тоже прокатывает?
     
  9. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    Если так, то тоже работает
    Код (Text):
    1.  
    2. class foo
    3. {
    4.    private function __construct()
    5.    {
    6.    ...
    7.    }
    8.  
    9.    public function GetFoo2()
    10.    {
    11.       $boo = new foo2;
    12.       $boo->PrintFoo();
    13.    }
    14.  
    15.    private function PrintFoo()
    16.    {
    17.       echo 'хаха я все равно работаю';
    18.    }
    19. }
    Добавлено спустя 1 минуту 14 секунд:
    Во всяком случае так работает в php 5.3.6 под Mac os x
     
  10. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    может конечно ща ктонить придет, и скажет, что так и задумано. Но я удивлен.
     
  11. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    Да я тоже удивился) Я всегда тоже считал,что если private то дочерний объект ну никак не может доступ получить.
     
  12. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    может баг запостить? =)
    может на хабр?
     
  13. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    Лучше баг запостить) Там если что, скажут что ты не оч умный) Впринципе как и на хабре)
     
  14. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    а что будет если из этого приват метода обратиться к переменной класса? интересно, какое значение она будет содержать. Вдруг родительское?

    ладушки, я спать.
     
  15. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    Вот:
    Код (Text):
    1.  
    2. class foo
    3. {
    4.    private $boo;
    5.    private function __construct()
    6.    {
    7.       $this->boo = 'parent';
    8.    }
    9.  
    10.    public static function GetInstance()
    11.    {
    12.    ...
    13.    }
    14.  
    15.    public function GetFoo2()
    16.    {
    17.       $temp = new foo2;
    18.       $temp->PrintFoo();
    19.       return $temp;
    20.    }
    21.  
    22.    private function PrintFoo()
    23.    {
    24.       echo $this->boo;
    25.    }
    26. }
    27.  
    28. class foo2 extends foo
    29. {
    30.    public function __construct()
    31.    {
    32.       $this->boo = 'child';
    33.    }
    34. }
    35.  
    36. $test = foo::GetInstance();
    37. $test = $test->GetFoo2();
    Выведет "parent"
     
  16. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Вот это прикол! (с)

    не знаю как, но мне кажется это дырка
     
  17. Clickbeetle

    Clickbeetle Активный пользователь

    С нами с:
    19 апр 2012
    Сообщения:
    16
    Симпатии:
    0
    У меня сейчас нет возможности проверить это на самой последней сброке php, а надо бы, и если там так, есть желание пойти баг запостить, ну или чтоб кто-нибудь пришел и сказал что так задумано)
     
  18. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    а что у тебя содержит метод GetInstance(); ?
     
  19. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    о, мозгов прибыло. авось что выясните.
     
  20. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    А у меня орет =)

    Fatal error: Call to private foo::__construct() from invalid context in =)))
     
  21. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
    ололо)) я бы никогда не подумал о такой фишке)) Хотя возможно просто невнимательно читал документацию.
    И дело совсем не в синглтоне, проблема воспроизводится с обычными объектами.

    Код (Text):
    1.  
    2. <?php
    3. class ParentClass
    4. {
    5.  
    6.     private function somePrivateParentFunction()
    7.     {
    8.         echo "It's private parent function";
    9.     }
    10.  
    11.     public function doSomethingWithChild()
    12.     {
    13.         $child = new ChildClass();
    14.         $child->somePrivateParentFunction();
    15.     }
    16.  
    17. }
    18.  
    19. class ChildClass extends ParentClass
    20. {
    21.  
    22. }
    23.  
    24. $parent = new ParentClass();
    25. $parent->doSomethingWithChild();
    Вывод: It's private parent function
     
  22. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    http://www.php.ru/manual/language.oop5.visibility.html
     
  23. tommyangelo

    tommyangelo Старожил

    С нами с:
    6 дек 2009
    Сообщения:
    2.549
    Симпатии:
    0
    Адрес:
    Мариуполь
  24. igordata

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

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    скорее всего некий механизм внутренний был сделан для скорости так, что методы просвечивают. на умышленное не похоже.
     
  25. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    очередная особенность реализации "истинного ООП" в пхп. ничего страшного.