我有一点问题。这是:
这是我的单身抽象类:
abstract class Singleton {
protected static $_instance = NULL;
/**
* Prevent direct object creation
*/
final private function __construct()
{
$this->actionBeforeInstantiate();
}
/**
* Prevent object cloning
*/
final private function __clone() { }
/**
* Returns new or existing Singleton instance
* @return Singleton
*/
final public static function getInstance(){
if(null !== static::$_instance){
return static::$_instance;
}
static::$_instance = new static();
return static::$_instance;
}
abstract protected function actionBeforeInstantiate();
}
之后我创建了一个抽象的注册表类:
abstract class BaseRegistry extends Singleton
{
//...
}
现在是会议注册的时候了。
class BaseSessionRegistry extends BaseRegistry
{
//...
protected function actionBeforeInstantiate()
{
session_start();
}
}
最后一步:
class AppBaseSessionRegistryTwo extends BaseSessionRegistry { //... }
class AppBaseSessionRegistry extends BaseSessionRegistry { //... }
测试
$registry = AppBaseSessionRegistry::getInstance();
$registry2 =AppBaseSessionRegistryTwo::getInstance();
echo get_class($registry) . '|' . get_class($registry2) . '<br>';
输出:
AppBaseSessionRegistry|AppBaseSessionRegistry
我的期望是:
AppBaseSessionRegistry|AppBaseSessionRegistryTwo
为什么我得到这样的结果? 我怎样才能重新制作代码以获得我期望的结果?
更新:我在我的框架中使用它。用户将扩展我的BaseSessionRegistry
课程并添加他们的内容。我想在我的框架类
答案 0 :(得分:4)
你需要这样做:
class AppBaseSessionRegistryTwo extends BaseSessionRegistry {
protected static $_instance = NULL;
// ...
}
class AppBaseSessionRegistry extends BaseSessionRegistry {
protected static $_instance = NULL;
//...
}
如果您没有单独声明静态属性,它们将共享其父级的静态属性。
的更新强> 的 如果您不希望子类声明静态属性,则可以将static属性声明为父类的数组。
abstract class Singleton {
protected static $_instances = array();
// ...
/**
* Returns new or existing Singleton instance
* @return Singleton
*/
final public static function getInstance(){
$class_name = get_called_class();
if(isset(self::$_instances[$class_name])){
return self::$_instances[$class_name];
}
return self::$_instances[$class_name] = new static();
}
abstract protected function actionBeforeInstantiate();
}
答案 1 :(得分:1)
你的第一行:
$registry = AppBaseSessionRegistry::getInstance();
将使用protected static $_instance
实例填充AppBaseSessionRegistry
。在您的下一行$registry2 =AppBaseSessionRegistryTwo::getInstance();
上,受保护的静态$ _instance已经有一个值,并且将返回该实例。
一般来说,单身人士和静电是邪恶的。结合它们是可怕的。从事良好的OO编程业务,避免单身人士和静态。
答案 2 :(得分:1)
$registry = AppBaseSessionRegistry::getInstance();
以上语句使用AppBaseSessionRegistry类的对象设置$ _instance 因为在getInstance方法中,我们检查它是否先前已设置然后返回 因此,你的第二个陈述的价值
$registry2 =AppBaseSessionRegistryTwo::getInstance();
getInstance将返回类AppBaseSessionRegistry的对象,即$ registry1和注册表2引用相同的对象