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

时间:2014-07-23 15:44:55

标签: php

我正在学习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();

我被告知

  

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

在上面的代码中,如果我通过

调用getProperty方法
// More code....
$newobj = new MyOtherClass;

// Attempt to call a protected method
echo $newobj->getProperty();

我会收到错误

  

致命错误:从上下文&#39;&#39;中调用受保护的方法MyClass :: getProperty()在..........

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

编辑:如果MyOtherClass继承了它父母的方法,那么现在它内部的方法/属性相同。如果是这样,不会

echo$newobj->getProperty() 

相同
echo $newobj -> callProtected();

从MyOtherClass类中访问它

1 个答案:

答案 0 :(得分:0)

对封装进行了基本的OOP访问限制。

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

受保护的访问 - 允许从类本身或继承的类(子类)进行访问。

私人访问 - 仅允许访问WITHIN类,而不是子级

另外,要深入了解什么是OOP并从一开始就遵循OOP的良好习惯 - 我建议你阅读SOLID,这是五个首要的oop原则。它们是OOP方法的关键。阅读并理解这些。 您可能还想阅读GRASP OOD原则。 - PEAR Coding Standard

还有一个共同的可接受的编码标准

公开示例

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