他们做两件不同的事情。的语义parent
关键字是这样的,它会对其父类进行转发调用。的语义$this->method()
然而,只有在调用该方法的实例未声明该方法的情况下,它才会将其调用转发给父类。同样重要的是要注意,孩子可能有父母和祖父母,因此在原型设计中也必须仔细考虑这一点。
如果您不希望该方法被覆盖,您应该使用final http://php.net/language.oop5.final方法原型声明中的关键字。
class MyClass {
final protected function myMethod() {
}
}
这确保了任何扩展类都无法重写该方法。如果扩展类尝试像下面的代码一样重写此方法,您将收到致命错误Fatal error: Cannot override final method MyClass::myMethod()
.
class MyOtherClass extends MyClass {
public function myMethod() {
}
}
另外,这使得你的代码更具可读性 and 不太容易出错因为您清楚地向任何阅读代码的人声明该方法是最终的并且不能被覆盖。
另外,你的方法的根本问题(如果你想使用parent::myMethod()
vs. $this->myMethod()
)是你没有考虑当班级是一个时会发生什么孙子它的父级,例如......
class Father {
protected function myMethod() {
return __METHOD__;
}
}
class Child extends Father {
public function myMethod() {
return __METHOD__;
}
}
class GrandChild extends Child {
public function myOtherMethod() {
echo parent::myMethod(), "\n"; // Child::myMethod
echo $this->myMethod(), "\n"; // Child::myMethod
}
}
$obj = new GrandChild;
$obj->myOtherMethod();
正如您所看到的,即使您想获取父亲的方法,它们都会为您提供子方法。如果您从不打算在扩展类中重写该方法,只需将该方法声明为final,并且从对象上下文调用 $this->myMethod() 时应该始终没问题。