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!
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启