new static和new self

这篇博客探讨了PHP中的`new static`和`new self`的区别,以及`self`、`$this`和`static`关键字的用法。在继承场景下,`new self`始终返回父类实例,而`new static`则返回实际调用方法的子类实例。`self`用于访问静态属性和方法,与`__CLASS__`类似,而`$this`指向调用对象,`static`则在静态和非静态方法中都可使用,具备后期静态绑定特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前几天看见一段代码出现了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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值