为什么我必须创建另一个方法从父类访问受保护的方法


Why do i have to create another method to access a protected method from a parent class?

我目前正在学习OOP PHP,当我遇到以下代码示例

代码:

class MyClass
{
    //Class methods and properties go here
    public $prop1 = "I'm a class property!";
    public function __construct()
    {
        echo 'The class "',__CLASS__,'" was initiated!<br />';
    }
    public function __destruct(){
        echo 'The class "',__CLASS__,'" was destroyed!<br />';
    }
    public function __toString()
    {
        echo "Using the toString method: ";
        return $this -> getProperty();
    }
    public function setProperty($newval)
    {
        $this -> prop1 = $newval;
    }
    protected function getProperty()
    {
        return $this -> prop1."<br />";
    }
}
class MyOtherClass extends MyClass
{
    public function __construct()
    {
        parent::__construct();
        echo"A new constructor in ".__CLASS__."<br />";
    }
    public function newMethod()
    {
        echo "From a new method in ".__CLASS__."<br />";
    }
    public function callProtected()
    {
        return $this -> getProperty();
    }
EDIT:: public $prop1 = "I'm a class property!";
    public function __destruct(){
        echo 'The class "',__CLASS__,'" was destroyed!<br />';
    }
    public function __toString()
    {
        echo "Using the toString method: ";
        return $this -> getProperty();
    }
    public function setProperty($newval)
    {
        $this -> prop1 = $newval;
    }
    protected function getProperty()
    {
        return $this -> prop1."<br />";
    }
}

$newobj = new MyOtherClass;
echo $newobj -> callProtected();

我被告知

当一个属性或方法被声明为受保护时,它只能在类本身或后代类(扩展包含受保护方法的类的类)中访问。

在上面的代码中,如果我要通过 调用getProperty方法
// More code....
$newobj = new MyOtherClass;
// Attempt to call a protected method
echo $newobj->getProperty();

就会得到错误

致命错误:调用保护方法MyClass::getProperty()从上下文"在..........

如果通过扩展MyOtherClass类,它应该继承其父类(MyClass)的所有方法和属性。如果是这样,为什么我不能简单地访问getProperty方法直接从MyOtherClass调用它?

编辑:如果MyOtherClass从它的父母继承的方法,那么相同的方法/属性现在在它里面。如果是的话,

echo$newobj->getProperty() 

相同
echo $newobj -> callProtected();

从MyOtherClass类内部访问它??

基本的OOP访问限制是为了封装而制定的。

公共访问-允许从任何地方(外部/内部)访问。

保护访问——允许从类本身或继承的类(子类)内部访问。

私有访问-只允许在类内访问,而不是子

另外,要深入理解什么是面向对象,并从一开始就遵循面向对象的好习惯——我建议你阅读SOLID,即五大面向对象原则。它们是OOP方法的关键。阅读并理解这些。你可能也想读一下《把握好原则》。还有一个普遍接受的编码标准——PEAR编码标准

<标题>公共示例
Class A {
  public $a = "hello oop world";
  public function getA()
  {
    return $this->a;
  }
}
# call successful in any case
$a = new A;
$a->getA(); // success
echo $a->a // success due to it's access public
<标题>保护示例
Class A {
  public $a = "hello OOP world";
  protected $_b = "Here we test protected";
  public function getA() {
    return $this->a;
  }
}
Class B extends A {
  public function getB() {
    return $this->_b;
  }
}
# test
$a = new A; #init
$b = new B; #init
echo $a->a; // success - prints "hello oop world"
echo $a->_b; // fails with access error.
echo $a->getA(); // success print hello oop world
echo $b->getA(); // also prints hello oop world (inherited all of the parent class!)
echo $b->getB(); // return the $_b ! why? it is inherited and we made public getter in child class!
<标题>私人示例
Class A {
  private $_sharedProperty = "Sometimes Private is good!"
  public function parentGetter() {
    return $this->_sharedProperty;
  }
}
Class B {
  public childGetter() {
    return $this->_sharedProperty;
  }
}
# Now we test, as we can see, both methods trying to access shared property.
$parent = new A; #instantiate
$child = new B; #instatiate
echo $parent->_sharedProperty; // Fails with access restricted.
echo $parent->parentGetter(); // print the shared property of instance.
echo $child->_sharedProperty   // Fails also with access restricted.
echo $child->childGetter(); // FAILS ! Why? Private is not available to child!

希望对你有帮助。

问候,

VR