2012-05-12 4 views
2

私は次のようなクラス階層を持っている:PHP:クラス階層内の同じ名前のメソッドをすべて呼び出すにはどうすればよいですか?

class Alpha { 
    public function initialize() { 
     $class = get_class($this); 
     $family = array($class); 
     while(($class = get_parent_class($class)) !== false) { 
      $family[] = $class; 
     } 
     $family = array_reverse($family); 
     foreach($family as $className) { 
      // call $className's start (instance) method 
     } 
    } 

    public function start() { 
     echo "calling start from Alpha\n"; 
    } 
} 

class Beta extends Alpha { 
    public function start() { 
     echo "calling start from Beta\n"; 
    } 
} 

class Charlie extends Beta { 
    public function start() { 
     echo "calling start from Charlie\n"; 
    } 
} 

$c = new Charlie(); 
$c->initialize(); 

アルファのinitializeメソッドが戻っアルファのstartメソッドへのすべての方法派生クラスのstartメソッドと同様に、派生クラスの上位クラススタート法のすべてを呼び出す必要があります。コードは次のような出力を生成する必要があります

calling start from Alpha 
calling start from Beta 
calling start from Charlie 

しかし、私は$ classNameの変数で指定された特定の祖先クラスのインスタンスメソッドを呼び出す方法を見つけ出すように見えることはできません。

私はcall_user_func(array($className, 'start'))を使用しましたが、これはスタティック関数のように扱われます。何か案は?クラス名のようなクラスの関数呼び出しで

+0

を開始? –

+1

私はすべての階層を見ることができません... – uttam

+0

なぜあなたは 'parent :: start()'を避けたいですか?それはちょっと "階層"の仕組みです。また、あなたの例では、3つのクラスは3つの別々のクラスです。ここには「階層」はありません。 –

答えて

2

::スタートはクラス名の関数を呼び出す必要がありません静的コールこれらの三つのクラスがどのように関連しているか

class Alpha { 

    public $myvar = 0; 

    public function initialize() { 

     $class = get_class($this); 
     $family = array($class); 
     while(($class = get_parent_class($class)) !== false) { 
      $family[] = $class; 
      $this->myvar ++; 
     } 
     $family = array_reverse($family); 
     foreach($family as $className) { 
      // call $className's start method 
      eval("{$className}::start();"); 
     } 
    } 

    public function start() { 
     echo "{$this->myvar} calling start from Alpha\n"; 
    } 
} 

class Beta extends Alpha { 
    public function start() { 
     echo "{$this->myvar} calling start from Beta\n"; 
    } 
} 

class Charlie extends Beta { 
    public function start() { 
     echo "{$this->myvar} calling start from Charlie\n"; 
    } 
} 

$c = new Charlie(); 
$c->initialize(); 
+0

なぜ 'eval'を使用していますか? '' :: :: ''メソッドを静的に呼び出します。これは '' call_user_func(array($ className、 'start')) 'と同じです。 –

+0

これは動作します。私は一般的にeval()の使用を避けようとしていますが、startメソッドをインスタンスメソッドとして呼び出すことができる別の解決策が見つからない場合は、おそらくこれに頼ります。 – Trevor

+0

@threed:この解決策は、あなたが言っていなかった 'call_user_func(array($ className、 'start'))'、(または 'call_user_func($ className。 ':: start')'やりたくない。 –

2
class Alpha { 
    public function initialize() { 
     // ... call all 'start' methods in class hierarchy starting with highest level  class (Alpha's start method) and ending with lowest derived class 
    } 

    public function start() { 
     echo "calling start from Alpha\n"; 
    } 
} 

class Beta extends Alpha { 
    public function start() { 
     echo "calling start from Beta\n"; 
     parent::start(); 
    } 
} 

class Charlie extends Beta { 
    public function start() { 
     echo "calling start from Charlie\n"; 
     parent::start(); 
    } 

    public function initialize() { 
     $this->start(); 
    } 
} 

$c = new Charlie(); 
$c->initialize(); 
+0

Alphaのinitializeメソッドは、すべての開始メソッドの呼び出しを行う必要があるという要件の1つです。 – Trevor

関連する問題