封装和继承方法

时间:2009-08-19 09:34:46

标签: php oop inheritance visibility encapsulation

我想知道是否可以封装类的方法,但是然后在消费类中公开它们。例如(JFTR,我知道这段代码是错误的)

class Consumer{
        public function __construct($obj){
            $this->obj = $obj;
            }

        public function doCommand(){
            $this->obj->command();
            }
        }

     class Consumed{
         //I would make the constructor private, but to save space...
         public function __construct(){}
         private function command(){
             echo "Executing command in the context of the Consumer";
             }
         }

     $consumer = new Consumer(new Consumed);
     $consumer->doCommand();

     //just to reiterate, I know this throws an error

最终,我希望能够创建无法在单个控制类的上下文之外直接引用的组件。

2 个答案:

答案 0 :(得分:1)

可以模仿与__calldebug_backtrace类似的内容。

<?php
class Consumer{
  public function __construct($obj){
    $this->obj = $obj;
  }

  public function doCommand(){
    $this->obj->command();
  }
}

class Consumed {
  // classes that are aloowed to call private functions
  private $friends = array('Consumer');

  public function __construct(){}
  private function command() {
    echo "Executing command in the context of the Consumer. \n";
  }

  public function __call($name, $arguments) {
    $dt = debug_backtrace();
    // [0] describes this method's frame
    // [1] is the would-be frame of the method command()
    // [2] is the frame of the direct caller. That's the interesting one.
    if ( isset($dt[2], $dt[2]['class']) && in_array($dt[2]['class'], $this->friends) ) {
      return call_user_func_array(array($this,$name), $arguments);
    }
    else {
      die('!__call()');
    }
  }
}

$c = new Consumed;
$consumer = new Consumer($c);
$consumer->doCommand();

echo 'and now without Consumer: '; 
$c->command();

打印

Executing command in the context of the Consumer. 
and now without Consumer: !__call()

答案 1 :(得分:0)

当然可以,只需制作这些方法protected,而不是privateConsumedConsumer延伸。我不确定这些好处。