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

黄舟
Libérer: 2023-03-06 16:50:01
original
2384 Les gens l'ont consulté

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

<?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); //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);
Copier après la connexion

后期静态绑定的 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 属性

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!