首页 > 学院 > 开发设计 > 正文

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

2019-11-08 01:24:51
字体:
来源:转载
供稿:网友
<?php// 单例模式之继承class Singleton{	PRotected static $ins = null;	private final function __construct() { }	protected final function __clone() { }	// public static function getIns() {		// if(self::$ins === null){			// self::$ins = new self();		// }		// return self::$ins;	// }		public static function getIns() {		if(static::$ins === null){			static::$ins = new static();		}		return static::$ins;	}}class Child extends Singleton{	// protected static $ins = null;}/*输出结果为:bool(true) object(Singleton)#1 (0) { }问题:对象 $c1, $c2 竟然都是 Singleton 的实例 ???解决方法:将 getIns() 方法中关键字 self 替换为 static, 利用后期静态绑定的特性*/$c1 = Child::getIns();$c2 = Child::getIns();var_dump($c1 === $c2); //truevar_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 属性


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表