self和parent的用法
self:本类,自身
parent:父类
使用场景:
- 首先请明确区分类和对象;
- 在使用本类/父类的,静态属性、方法时,会用到;
- self 在本类中使用,用于引用自身的静态属性和方法;
- parent 在子类中使用,用于引用父类的静态属性和方法(包括普通的方法,但是私有的不可被访问);
用法:
- self::$staticProperty;
- self::staticMethods();
- parent::$staticProperty;
- parent::Methods();
使用规范:
- 在本类中就用self
- 在子类中就用parent
- 如果是子类继承过来的属性或者方法,最好是使用 this更符合面向对象;
单例模式
单例模式就是一个类不能使用new
关键字进行实例化对象,通过调用类的静态方法创建一个实例对象,并且只能创建一个;符合这个条件的,都是单例模式,单例单例,就是只有一个实例。逢面必问!
- 示例:
//单例模式
class D{
final protected function __construct(){
echo '单例模式';
}
static $obj = null;
static public function init(){
if (self::$obj instanceof self) {
return self::$obj;
}
self::$obj = new self();
return self::$obj;
}
}
$a = D::init();
class C extends E{}//这一行报错
instanceof
关键字是专门用来判断某个实例对象是不是某个类的实例,是返回true,否则返回false;final
关键词:如果类用final来修饰,则不能被继承,如果是方法用final来修饰,则被继承之后,只读不可写,不能被子类覆盖重写;- 如果类的构造函数可以被重写,那么单利模式的意义则不存在了;他依旧可以有很多个实例;
__clone()方法
- 在上面实现的单例模式中存在一个问题:当使用类的唯一实例对象进行克隆之后,得到了另一个一模一样的对象,但在内存中并不指向同一个类,这样就很不单例;
- 解决办法:在类中使用
__clone
函数, - 示例:
class A {
public function __clone(){
return false;
}
}
$a = new A();
$b = clone $a;
- 在上述例子中,
$b
克隆了$a
对象,则,$b
的值为false
; - 也就是说
__clone
方法会在类的实例对象被被控时执行一个函数,你可以做一些操作,比如为当前实例对象增加一些新属性,新方法等; - 那么,上面单例模式中,类实例会被克隆的问题就解决了,在
__clone
方法中进行判断,如果自身的$obj
属性是类实例,则返回这个对象;