2012-03-02 4 views
2
abstract class Mother { 
     protected static $foo = null; 
     protected static $bar = null; 

     public function getFoo() { return static::$foo; } 
     public function getBar() { return static::$bar; } 
     public function setFoo($foo) { static::$foo = $foo; } 
     public function setBar($bar) { static::$bar = $bar; } 
} 

class Brother extends Mother { 
     protected static $foo = 'BROTHERS'; 
} 

class Sister extends Mother { 
     protected static $foo = 'SISTERS'; 
} 

$brother1 = new Brother(); 
$brother2 = new Brother(); 
$sister1 = new Sister(); 
$sister2 = new Sister(); 

$sister1->setBar('ONLY SISTERS'); // We set $bar = 'ONLY SISTERS' at sister1. 
// We want only Sister instances to get this value... 
// however Brother instances also get this value! 

    echo '<p>Brother 1: Foo="'.$brother1->getFoo().'", Bar="'.$brother1->getBar().'"</p>'; 
// Foo="BROTHERS", Bar="ONLY SISTERS" 
    echo '<p>Brother 2: Foo="'.$brother2->getFoo().'", Bar="'.$brother2->getBar().'"</p>'; 
// Foo="BROTHERS", Bar="ONLY SISTERS" 
    echo '<p>Sister 1: Foo="'.$sister1->getFoo().'", Bar="'.$sister1->getBar().'"</p>'; 
// Foo="SISTERS", Bar="ONLY SISTERS" 
    echo '<p>Sister 2: Foo="'.$sister2->getFoo().'", Bar="'.$sister2->getBar().'"</p>'; 
// Foo="SISTERS", Bar="ONLY SISTERS" 

Таким образом, если статический :: $ бар явно не переопределен для каждого дочернего элемента (Брат, Сестра), их родитель (Мать) установит для них значение (или, по крайней мере, для тех, кто не переопределял его).PHP: Ограничение области статической переменной до определенного класса

Вопрос: Есть ли способ предотвратить детей, которые не переопределили статические :: $ bar от получения нового значения? Другими словами, как убедиться, что только связанный класс получает новое значение, ДАЖЕ, если static \ $ bar явно не переопределяется в каждом дочернем?

+1

Я вижу только один вариант для достижения этой цели. Вы должны перезаписать методы getBar и setBar в родном классе. Метод setBar записывает в $ this-> bar, и getBar проверяет, установлен ли $ this-> bar и извлекается из parent :: $ bar в противном случае. – Dan

+0

Есть ли причина иметь эти статические, когда у вас есть экземпляр объекта? –

+0

@Dan Возможно, вы правы. Другой вариант - повторно объявить static :: $ bar в каждом дочернем элементе. Проблема в том, что не существует способа заставить программиста сделать это. – mae

ответ

2

Нет, не так, как вы это делаете. Для этого нужен частный охват. Классы Child наследуют все общедоступные и защищенные статические свойства, что означает, что все они указывают на одно и то же значение, являются ли они родителем, дочерним или родственным.

Это правильно и хорошо OO.

Вы должны определить переменную как private static в родительском классе, а потом ребенок не сможет увидеть ее напрямую и может создать свою собственную старую переменную с тем же именем, если это необходимо.

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

Brother::getFoo(); 
Sister::getFoo(); 

Вы можете сделать getFoo() в родительском классе Матери абстрактной или нет, если вам нужно получить к нему доступ непосредственно сделать его неабстрактным, так что вы можете сделать:

Mother::getFoo(); 
+0

Хорошо, я думаю, что это правильное направление, но мне нужно более подробно о том, как (и где) именно реализовать эти функции, в частности, getter/setter $ bar, потому что я продолжаю получать эту ошибку за все, что я пытаюсь: _Fatal error: Не удается открыть свойство Sister :: $ bar_ – mae

+0

Должен ли я предоставлять статические геттеры/сеттеры в ** каждый ** дочерний класс? – mae

+0

Вы можете создать его в классе Mother, и он получит доступ к матерью :: $ bar с помощью Mother :: getBar(). Да, вам нужно будет внедрить геттеры и сеттеры для всех классов, поскольку $ bar является частным для Мамы. – Ray

1

Это просто безумие.

Вы должны понимать, что extend определяет IS A отношений. Например: class Duck extends Bird{} это означает, что каждый экземпляр Duck является Bird.

Так что в вашем примере каждый Brother является Mother. Я не понимаю, как это будет иметь смысл.


И еще: почему, черт возьми, вы злоупотребляете статическими переменными? То, что вы там делаете, не является объектно-ориентированным программированием. Вы просто обертываете глобальные переменные и функции в пространстве имен (что похоже на класс).

Некоторые дополнительные ссылки на эту тему, вы могли бы оказаться полезными:

+0

Итак, вы думаете, что лучше иметь копию той же строки в каждом подклассе? – mae

+0

@ пользователь1132363, какой? Где я это сказал? Возможно, вам следует узнать об инъекции зависимостей. –

+1

Ну, вы явно подразумеваете, что я не должен использовать статические переменные. По крайней мере, не так, как я это делаю сейчас, но вы не предложили альтернативного решения. – mae

Смежные вопросы