Yöntemleri Encapsulating ve miras

2 Cevap php

Hi all I'm wondering if it's possible to encapsulate the methods of a class, but then expose them within a consuming class. For example (JFTR, I know this code is wrong)

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

Sonuçta, ben doğrudan bir tek kontrol sınıf bağlamı dışında başvurulan olamaz bileşenler yapabilmek istiyorum.

2 Cevap

Tabii bu, sadece bu yöntemleri protected, değil private yapmak ve Consumed Consumer uzanır olabilir. Ama yararları hakkında emin değilim.

Sen could __call ve debug_backtrace ile benzer bir şey taklit.

<?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();

baskılar

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