简体   繁体   中英

How do I refer to a child class variable from an inherited parent class method in PHP?

Say I have two classes:

class ParentClass
{
     public function getSomething()
     {
         return $this->variable_name;
     }
}

class ChildClass extends ParentClass
{
    private $variable_name = 'something specific to child class';
    ...
}

Then I call code to instantiate the ChildClass and call the inherited getSomething() method:

$object = new ChildClass();
$value = $object->getSomething();

When I call that last line, it gives me an error because $variable_name does not exist in ParentClass . I'm expecting ChildClass to inherit the method getSomething() , but I understand that since it is not overridden explicitly in ChildClass , it uses the parent's scope when running the parent version of the method.

How can I most efficiently have the ChildClass inherit the method and give it the ability to read the child class's $variable_name when said method is called?

Rule of thumb: if your parent class needs to know anything about child classes, then you do something wrong.

When you design classes or interfaces you should first think about actions (methods) which they can perform. Don't think about their internal state (variables).

To solve your particular problem, you should first decide, whether you need to have different object states or different actions.

For different states, you could implement something like this:

class ParentClass {
    private $variable;
    function __construct($var) {
        $this->variable = $var;
    }
    function getSomething() {
        return $this->variable;
    }
}
class ChildClass extends ParentClass {
    function __construct() {
        parent::__construct('something specific to child class');
    }
}

so, variable is part of Parent's state and child object must init it.

another approach is to make contract:

abstract class ParentClass {
    function getSomething() {
        return $this->internalGetSomething();
    }
    abstract function internalGetSomething();
}
class ChildClass extends ParentClass {
    function internalGetSomething() {
        return 'something specific to child class';
    }
}

so, internalGetSomething is contract between parent and child

Short answer: You can't.

Long answer: That's not how OO works. Parent classes doesn't know your childs. What you can do is to use Reflection, but it's not the way to go, you need to rethink your project.

class Parent {
    public function getSomething(Child $child) {
        $reflection = new ReflectionObject($child);
        $variable_name = $r->getProperty('variable_name');
        $variable_name->setAccessible(true);
        return $variable_name->getValue($child);
    }
}

Just like you stated, the ChildClass inherits from the ParentClass, not the other way around. To the ParentClass, $this->variable_name is an unknown variable. A simple way that I would suggest would be to change the ParentClass method a bit and override it in the ChildClass as such:

class ParentClass
{
    public function getSomething($param)
    {
        return $param;
    }
}

class ChildClass extends ParentClass
{
    private $variable_name = 'something specific to child class';

    public function getSomething($param = "")
    {
        return parent::getSomething($param = $this->variable_name);
    }
}

$object = new ChildClass();
$value = $object->getSomething();
echo $value;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM