gpt4 book ai didi

php - 从 PHP 中的子类访问 protected 方法

转载 作者:可可西里 更新时间:2023-11-01 00:34:11 25 4
gpt4 key购买 nike

我至少可以使用两种基本方法从子类访问 protected 类方法:

parent::myMethod();

$this->myMethod();

如果我不需要在子类中覆盖它,在这种情况下我必须这样做:

function myMethod() {
...
parent::myMethod();
...
}

最推荐的调用方式是什么?我个人觉得使用 parent::myMethod() 而不是 $this->myMethod 更舒服,因为第一个立即告诉我这个方法正在被继承。但我不确定在性能和最佳实践方面采用哪种方式。

编辑:

检查这个,这是我问题的真实情况。它使用 CodeIgniter,但即使您不熟悉它,您也可能会了解它:

class Admin_Controller extends CI_Controller {

protected function validate_form($validation) {
$this->load->library('form_validation');
// This will validate the form sent against the validation rules group specified in $validation
if ($this->form_validation->run($validation) == false) {
throw new Exception('There are errors in the form');
}
}

}

class Articles extends Admin_Controller {

function save($id) {
$this->validate_form(strtolower(get_class($this));
// OR
parent::validate_form(strtolower(get_class($this));
// Other actions
....
}

}

class Login extends Admin_Controller {

function signIn() {
$this->validate_form(strtolower(get_class($this));
// OR
parent::validate_form(strtolower(get_class($this));
// Other actions
....
}

}

最佳答案

他们做两件不同的事情。 parent 关键字的语义是将调用转发到其父类。然而,$this->method() 的语义是这样的,它只会在调用该方法的实例未声明该方法的情况下将其调用转发给父类.同样重要的是要注意, child 可能有 parent 和祖 parent ,因此在设计原型(prototype)时也必须仔细考虑这一点。

如果您不想覆盖该方法,您应该使用 final方法原型(prototype)声明中的关键字。

class MyClass {
final protected function myMethod() {
}
}

这确保了任何扩展类都无法覆盖该方法。如果扩展类试图像下面的代码一样覆盖此方法,您将收到 fatal error Fatal error: Cannot override final method MyClass::myMethod()

class MyOtherClass extends MyClass {
public function myMethod() {
}
}

此外,这使您的代码更具可读性并且更不容易出错,因为您清楚地向阅读代码的人声明该方法是最终的并且不能被覆盖。

此外,您的方法的潜在问题(如果您想使用 parent::myMethod()$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() 时应该始终没问题。

关于php - 从 PHP 中的子类访问 protected 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13763999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com