前几天看见一段代码出现了new self(),没看懂什么意思,于是百度了下。
一、new static()和new self()?
两者都是实例化自身,区别在于继承。如果没有继承,则两者返回的实例都是属于一个类;如果有继承,子类调用该方法,new self 仍然返回原类的实例,而 new static 返回实际子类的实例。这就是延迟静态绑定,static 的值,使用的是最后实际调用那个方法的类。
<?php
//示例
class A
{
public static $a = 1;
public function test()
{
$s = new static();
echo $s::$a;
}
public function test2()
{
$s = new self();
echo $s::$a;
}
}
class B extends A
{
public static $a = 2;
}
$t = new B();
$t->test();// 输出2
$t->test2();//输出1
二、self与this
了解了new self和new static是不是疑惑又来了,self、$this、static、parent这些关键字又是啥?
其实self、static上面已经说到了,上面的代码也可以这样写
class A
{
public static $a = 1;
public function test()
{
echo static::$a;
}
public function test2()
{
echo self::$a;
}
}
class B extends A
{
public static $a = 2;
}
$t = new B();
$t->test();// 输出2
$t->test2();//输出1
总结一下
1.self 和 __CLASS__,都是对当前类的静态引用,取决于定义当前方法所在的类。也就是说,self 写在哪个类里面, 它引用的就是谁。
2.self 可以用于访问类的静态属性、静态方法和常量,但 self 指向的是当前定义所在的类,这是 self 的限制。一个方法被self:: 后,它就自动转变为静态方法
3.$this 指向的是实际调用时的对象,也就是说,实际运行过程中,谁调用了类的属性或方法,$this 指向的就是哪个对象。但 $this 不能访问类的静态属性和常量,且 $this 不能存在于静态方法中。
4.$this 指向的对象所属的类和 static 指向的类相同。
5.static 关键字除了可以声明类的静态成员(属性和方法)外,还有一个非常重要的作用就是后期静态绑定。
6.static 可以用于静态或非静态方法中,也可以访问类的静态属性、静态方法、常量和非静态方法,但不能访问非静态属性。
7.静态调用时,static 指向的是实际调用时的类;非静态调用时,static 指向的是实际调用时的对象所属的类。
8.self 和 parent 没有什么说的;定向的
9.$this , static 随着运行,动态发生改变;可以这么说,static 是$this 的升级版。($this指定的变化的对象,static 指定的是变化的类);
为什么$this 不能访问类的静态属性和常量,且 $this 不能存在于静态方法中?
静态方法里不能使用this
静态方法随着类的加载而加载,静态方法是优先于对象而存在的。当我们加载一个类的时候,对象还没有存在,而this代表的是对象的引用,试问当我们加载类的时候对象都没有,又怎么可以使用this呢?答案显而易见
this是指当前对象,静态方法是通过类调用的方法,不需要实例化,既然不需要实例化,就没有当前对象,既然没有当前对象,就不会有this
静态变量可以使用slef:: 、 类名::、static:: 访问,不能使用$this访问;反之,类的成员变量未声明为const及static时,只能使用$this访问,不能用::访问。
静态函数既可以通过类调用,也可以通过实例调用。$this 作为对实例的引用,自然也可以调用静态函数。
静态方法不能调用非静态属性。因为非静态属性需要实例化后,存放在对象里
至于详细解释参考:https://segmentfault.com/q/1010000004142177