在php里不可避免的都会涉及面向对象的问题,而面向对象就肯定会遇到继承和单例,那如果父类是单例模式的,子类该怎么继承呢?
要说明这个问题,还是先来谈一谈php类里的get_class(获取当前的类名)、get_called_class(获取静态绑定后的类名)、self和__CLASS__(获取当前的类名)这四者的指向问题。
get_class、self、__CLASS__这三个的指向基本是一样的,它们都是指向当前类,可以这么理解就是说即使它们所在的类(就是它们所存在的类里,再通俗地说就是代码在所在的类),被子类继承了,它们还是会指向父类的(也就是它们存在的那个类),所以只能调用父类的方法和属性。
而get_called_class则不同,通过静态绑定它可以指向子类,也就可以调用子类的方法和属性了。
下面用代码来进行解释:
class A{ //父类
private static $ins = null;
public static function foo(){ //实现单例模式
$cls = get_class(); //$cls = __CLASS__也一样
if( !self::$ins instanceof self )
self::$ins = new $cls();
//这里如果new的是self也一样,都只能指向A这个类
return self::$ins;
}
public function demo(){
echo '父类里的demo方法';
}
}
class B extends A{ //继承于A的子类
public function demos(){
echo '子类的demo方法';
}
}
B::foo()->demo();//父类里的demo方法
从上面的代码可以看出来,子类创建的对象,并不能调用子类的方法,事实上就是因为父类的foo函数里,new对象时用的是get_class(),当然如果是__class__或者self效果也一样,他们都只能指向A这个父类。那怎么样才能让子类创建的对象可以指向子类ne,其实特别简单,只有把A类foo函数里的$cls = get_class()改成$cls = get_called_class()就可以了。因为get_called_class是获取静态绑定后的类名,我们用子类去绑定它,当然它就指向子类了。