PHP中的self::和parent::在继承中有什么区别?

29

当静态子类继承静态父类时,我想知道在使用self::和parent::之间有什么区别,例如:

class Parent {

    public static function foo() {
       echo 'foo';
    }
}

class Child extends Parent {

    public static function func() {
       self::foo();
    }

    public static function func2() {
       parent::foo();
    }
}

func()和func2()之间有什么区别,如果有的话,请问是什么?

谢谢

敬礼


18
如果你在子类中重写了foo(),那么self::foo()调用的是子类版本,而parent::foo()调用的是原始父类版本。 - Mark Baker
1
+1,应该是答案。 - Flosculus
1
static::foo() 让它变得更有趣 :) - Mark Baker
好的,但是如果子类没有自己的foo()定义,那么这是否意味着两个调用之间没有区别,即self::和parent::? - djkprojects
2
如果子类没有覆盖 foo() 方法,那么它将执行父类的 foo() 代码... 调用方式有所不同,但执行的内容是相同的。调用 parent::foo() 将始终执行父类的 foo() 方法,即使子类对其进行了覆盖;调用 self::foo() 将执行 foo() 的覆盖版本(如果在 self 中存在),否则将执行父类的 foo() 如果没有覆盖存在。 - Mark Baker
谢谢,那么结果完全相同的区别是什么?我理解self::和parent::之间的区别,但在上述情况下不清楚 :) - djkprojects
2个回答

64
                Child has foo()     Parent has foo()
self::foo()        YES                   YES               Child foo() is executed
parent::foo()      YES                   YES               Parent foo() is executed
self::foo()        YES                   NO                Child foo() is executed
parent::foo()      YES                   NO                ERROR
self::foo()        NO                    YES               Parent foo() is executed
parent::foo()      NO                    YES               Parent foo() is executed
self::foo()        NO                    NO                ERROR
parent::foo()      NO                    NO                ERROR
如果您正在寻找其正确使用的情况,parent 允许访问继承类,而 self 是对运行该方法(静态或其他方式)所属的类的引用。
在 PHP 中使用 Singleton 模式时,self 关键字的一个常见用途是,它不支持子类,而 static 则支持。详见New self vs. new static parent 提供了访问继承类方法的能力,通常在需要保留一些默认功能时非常有用。

谢谢,现在假设Child没有自己的foo()方法,并且以后也不会有,那么在使用self::或parent::关键词时,场景5和场景6之间有什么区别?它们可以交替使用吗?我的问题只涉及到这些特定情况。谢谢。 - djkprojects
2
我认输了!你赢了!如果你能提供那些铁一般的保证,并且你并不是试图混淆任何看你代码的人(包括六个月后的自己),那么执行的结果没有区别,你可以根据需要互换使用它们! - Mark Baker
谢谢Mark,为了不让任何人感到困惑,这些情况是否有更可取的版本?我认为parent::foo()更加说明性。你的方法是什么?谢谢。 - djkprojects
6
我会采用晚期静态绑定的方法,使用 static::foo(),除非我想要强制调用 parent::foo()...... 这样可以让我在将来实现子类的 foo() 方法(如果我愿意的话)... 甚至进一步扩展子类... 尽管很大程度上取决于具体需求。 - Mark Baker
嗨@Mark Baker + 1 - 在使用静态::继承时,PHP会首先查找最初调用的类,如果没有找到,则会去查找父类?提前致谢。 - user19481364

0

self用于调用静态函数和操作静态变量,这些变量是类特定的而不是对象特定的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接