duankan6894 2015-02-17 03:42
浏览 63
已采纳

是否有可能(以某种方式?)在PHP接口中声明构造函数的格式(或任何有关它的东西)?

I would like some feedback on my coding approach (i.e., whether it is appropriate or whether what I have done can be done in a perhaps better way):

I would like to create an interface to document that a constructor should have a specific format. Of course, if the interface only contains a constructor (and I was even surprised that PHP lets you put a constructor in an interface), the interface will have no effect (except for possibly documentation). Besides, PHP does not enforce the parameters of any callable to match, neither in number nor in type, and this is true of functions, methods, and constructors alike.

If you see how I have named my classes, you will realize what I am trying to do (: document that the constructor parameter must be a messager instance, too bad I could not do more to enforce this). Please let me know if my approach is OK and whether I can improve it.

class Messenger {

  private $message;

  function __construct($message = "Hello!") {

    $this->message = $message;

  }

  public function getMessage() {

    return $this->message;

  }

}

With the above simple class in mind, I want to create an interface such as the following, but since we're dealing with a PHP constructor this should be useless?

interface MessengerAware {

  function __construct($messenger);

}

class MessengerKnower implements MessengerAware {

  private $messenger;

  function __construct($messenger) {

    $this->messenger = $messenger;

  }

  public function displayMessengerMessage() {

    echo $this->messenger->getMessage();

  }

}

I then want to enforce my interface in a class called Runner such as the following:

class Runner {

  private $messengerAware;

  function __construct($messengerAware) {

    if (!is_a($messengerAware, 'MessengerAware')) {

      die("I'm expecting an instance implementing the MessengerAware interface.");

    }

    $this->messengerAware = $messengerAware;

  }

  public function run() {

    echo "I'm running.
";

    $this->messengerAware->displayMessengerMessage();

  }

}

and finally run this code:

$messengerAware = new MessengerKnower(new Messenger());
$runner = new Runner($messengerAware);
$runner->run();

OUTPUT:

I'm running.
Hello!
  • 写回答

1条回答 默认 最新

  • douzhi7070 2015-02-17 04:11
    关注

    Perhaps it's not possible, but the problem could be worked around using one (or more) factory methods:

    Leave this unchanged:

    class Messenger {
    
      private $message;
    
      function __construct($message = "Hello!") {
    
        $this->message = $message;
    
      }
    
      public function getMessage() {
    
        return $this->message;
    
      }
    
    }
    

    This modification...

    interface MessengerAware {
    
      public static function create($messenger);
    
      public function displayMessengerMessage();
    
    }
    

    and this one...

    class MessengerKnower implements MessengerAware {
    
      private $messenger;
    
      public static function create($messenger) {
    
        $messengerKnower = new MessengerKnower();
    
        $messengerKnower->messenger = $messenger;
    
        return $messengerKnower;
    
      }
    
      public function displayMessengerMessage() {
    
        echo $this->messenger->getMessage();
    
      }
    
    }
    

    Leave this unchanged...

    class Runner {
    
      private $messengerAware;
    
      function __construct($messengerAware) {
    
        if (!is_a($messengerAware, 'MessengerAware')) {
    
          die("I'm expecting an instance implementing the MessengerAware interface.");
    
        }
    
        $this->messengerAware = $messengerAware;
    
      }
    
      public function run() {
    
        echo "I'm running.
    ";
    
        $this->messengerAware->displayMessengerMessage();
    
      }
    
    }
    

    Finally adjust this code:

    $messengerAware = MessengerKnower::create(new Messenger());
    $runner = new Runner($messengerAware);
    $runner->run();
    

    OUTPUT:

    I'm running.
    Hello!
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 求解vmware的网络模式问题
  • ¥24 EFS加密后,在同一台电脑解密出错,证书界面找不到对应指纹的证书,未备份证书,求在原电脑解密的方法,可行即采纳
  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥30 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?