Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从PHP中继承的父类方法引用子类变量?_Php_Class_Oop_Inheritance_Methods - Fatal编程技术网

如何从PHP中继承的父类方法引用子类变量?

如何从PHP中继承的父类方法引用子类变量?,php,class,oop,inheritance,methods,Php,Class,Oop,Inheritance,Methods,假设我有两门课: class ParentClass { public function getSomething() { return $this->variable_name; } } class ChildClass extends ParentClass { private $variable_name = 'something specific to child class'; ... } 然后我调用代码来实例化

假设我有两门课:

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

class ChildClass extends ParentClass
{
    private $variable_name = 'something specific to child class';
    ...
}
然后我调用代码来实例化
ChildClass
,并调用继承的
getSomething()
方法:

$object = new ChildClass();
$value = $object->getSomething();
当我调用最后一行时,它给出了一个错误,因为
$variable\u name
父类中不存在。我希望
ChildClass
继承方法
getSomething()
,但我理解,由于它在
ChildClass
中未被显式重写,因此在运行方法的父版本时,它使用父级的作用域


我如何才能最有效地让
ChildClass
继承该方法,并在调用该方法时赋予它读取子类
$variable\u name
的能力?

简短回答:你不能

长回答:OO不是这样工作的。家长不了解你的孩子。 你可以做的是使用反射,但这不是一种方法,你需要重新思考你的项目

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);
    }
}
经验法则:如果您的父类需要了解有关子类的任何信息,那么您就做错了

在设计类或接口时,应首先考虑它们可以执行的
操作
(方法)。不要考虑它们的
内部状态
(变量)

要解决您的特定问题,您应该首先决定是否需要有不同的对象状态或不同的操作

对于不同的州,您可以实现如下内容:

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');
    }
}
所以,变量是父对象状态的一部分,子对象必须初始化它

另一种方法是订立合同:

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

因此,internalGetSomething是父类和子类之间的契约

正如您所述,子类继承自父类,而不是相反。对于父类,
$this->variable\u name
是未知变量。我建议的一种简单方法是稍微更改ParentClass方法,并在ChildClass中重写它:

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;

让它受到保护,而不是隐私。Private意味着它只属于那个类和那个类(没有继承):vs如果某个子类没有这个变量怎么办?家长应该怎么做?当然,我会检查变量是否存在。谢谢你的评论,Robbie。我完全忽略了这一点。这不是OOP的工作方式,你不应该检查子类中的变量,在许多其他语言中,如果没有黑客,你将无法做到这一点,你应该考虑接口/契约和方法/操作,暂时忘掉变量吧,我会考虑如何以不同的方式解决这个问题。我承认,我几乎没有接受过PHP方面的OOP正式培训,而且大部分都是在工作中学习的(无论是工薪阶层还是自由职业者)。甚至问这个问题我都觉得很愚蠢,因为我知道我遗漏了一些东西。谢谢你的耐心!我不同意这种说法。您的第二个示例以及在子类中使用接口是一个完美的示例,说明家长将确切知道子类将做什么。同意,它不应该访问属性,而是methods@robbie-averill否,父项声明合同,子项必须遵守。也许这个特殊的例子不能很好地说明这个概念。但这里我们有一个具体的问题