当前位置:Gxlcms > PHP教程 > 详解PHP单例模式之继承碰见的问题

详解PHP单例模式之继承碰见的问题

时间:2021-07-01 10:21:17 帮助过:6人阅读

详解PHP单例模式之继承碰见的问题

  1. <?php
  2. // 单例模式之继承
  3. class Singleton
  4. {
  5. protected static $ins = null;
  6. private final function construct() { }
  7. protected final function clone() { }
  8. // public static function getIns() {
  9. // if(self::$ins === null){
  10. // self::$ins = new self();
  11. // }
  12. // return self::$ins;
  13. // }
  14. public static function getIns() {
  15. if(static::$ins === null){
  16. static::$ins = new static();
  17. }
  18. return static::$ins;
  19. }
  20. }
  21. class Child extends Singleton
  22. {
  23. // protected static $ins = null;
  24. }
  25. /*
输出结果为: bool(true) object(Singleton)#1 (0) { } 问题:对象 $c1, $c2 竟然都是 Singleton 的实例 ??? 解决方法:将 getIns() 方法中关键字 self 替换为 static, 利用后期静态绑定的特性 */ $c1 = Child::getIns(); $c2 = Child::getIns(); var_dump($c1 === $c2); //true var_dump($c1); // ------------------------------------------------------------------------ // 另一个问题 /* 输出结果为: bool(true) object(Child)#1 (0) { } 问题:对象 $c3 竟然是 Child 的实例, 实际上应该是 Singleton 的实例 ??? 原因:因为 $ins 属性是从父类 Singleton 继承过来的, 当第一次调用 Child::getIns() 时, $ins = new Child() 当再次调用 Singleton::getIns() 时, $ins 已经被实例过了, 而且指向 Child 的实例, 所以此时 $c3 变成了 Child 的实例 解决方法:在 Child 类中, 声明自己独有的 $ins 属性 */ $c3 = Singleton::getIns(); var_dump($c1 === $c3); var_dump($c3);

后期静态绑定的 getIns() 方法还会有一个问题:

若 Singleton 的 $ins 属性被设置为 private 的,子类 Child 必须设置自己的 $ins 属性,

因为 static::$ins 优先寻找子类自己的 $ins 属性,但由于子类没有声明且父类的不能继承,此时调用 Child::getIns()

方法便会报错:

Fatal error: Cannot access property Child::$ins in D:\wamp\www\mycode\DesignPattern\Singleton.php on line 27

解决方法:

将父类 Singleton 的 $ins 属性设置为 protected 的 或者 设置子类 Child 自己的 $ins 属性

以上就是详解PHP单例模式之继承碰见的问题的详细内容,更多请关注Gxl网其它相关文章!

人气教程排行