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" 

static :: $ barがすべての子(Brother、Sister)で明示的に再定義されていない場合、親(Mother)それを再定義しなかった人のために)。PHP:静的変数のスコープを特定のクラスに限定する

質問:static :: $ barを再定義しなかった子供が新しい値を受け取るのを防ぐ方法はありますか?言い換えれば、参照されたクラスのみが新しい値を取得する方法、static :: $ barがすべての子で明示的に再定義されない場合でもEVEN?

+1

を私はこれを達成するための唯一のオプションを参照してください。姉妹クラスのgetBarメソッドとsetBarメソッドを上書きする必要があります。 setBarメソッドは$ this-> barに書き込み、getBarは$ this-> barが設定されているかどうかをチェックし、そうでなければparent :: $ barから取得します。 – Dan

+0

オブジェクトインスタンスがあるときにこれらの静的な理由がありますか? –

+0

@ダンあなたはおそらく正しいでしょう。別のオプションは、すべての子にstatic :: $ barを再宣言することです。問題は、プログラマにこれを強制する方法がないことです。 – mae

答えて

2

いいえ、あなたのやり方ではありません。それがプライベートスコープです。子クラスはすべてのpublicおよびprotected staticプロパティを継承します。つまり、親、子、兄弟のいずれであっても、すべて同じ値を指しています。

これは正しいOOです。

変数を親クラスのprivate staticとして定義する必要があります。子クラスはそれを直接見ることができず、必要に応じて同じ名前の独自の静的変数を作成することができます。

プライベート静的プロパティにアクセスするために、クラス内に静的ゲッターとセッターを用意します。

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

あなたがそうあなたが行うことができます直接アクセスそれは非抽象にする必要がある場合は、抽象的かどうか、親クラスの母でからgetfoo()を作ることができます。

Mother::getFoo(); 
+0

これは正しい方向だと思いますが、これらの機能、特に$ bar getter/setterをどのように(そしてどこで)実装するかについての詳細が必要です。プロパティSister :: $ bar_にアクセスできません – mae

+0

**すべての**子クラスに静的ゲッター/セッターを用意する必要がありますか? – mae

+0

Motherクラスで作成すると、Mother :: getBar()でMother :: $バーにアクセスします。はい、$ barは母親にはプライベートなので、すべてのクラスに対してgetterとsetterを実装する必要があります。 – Ray

1

はこれがちょうどです狂気。

extendIS Aの関係を定義していることを理解してください。たとえば、class Duck extends Bird{}は、DuckのすべてのインスタンスがBirdであることを意味します。

あなたの例では、BrotherはすべてMotherです。私はこれがどのように意味をなされるのか分からない。


もう1つの理由:なぜあなたは静的変数を悪用していますか?あなたがしていることは、オブジェクト指向プログラミングではありません。名前空間内のグローバルスコープ変数と関数をラップするだけです(クラスのように見えます)。

テーマに関するいくつかの追加のリンク、あなたは役に立つかもしれません:

+0

だから、あなたはすべてのサブクラスに同じ文字列のコピーを持つ方が良いと思いますか? – mae

+0

@ user1132363、何ですか?私はどこでそれを言ったのですか?多分あなたは依存性注入について学ぶべきです。 –

+1

あなたは、私が静的変数を使用してはならないことを明確に暗示しています。少なくとも私が今やっているやり方ではありませんが、あなたは何か別の解決策を提示しませんでした。 – mae

関連する問題