如何使用子类更改父元素属性

时间:2016-09-29 09:20:14

标签: php class oop

我正在尝试使用我的子类更改父类中的属性,但我没有得到我期望的结果。 我做了一些研究(比如Change parent variable from child class),但我似乎无法找到问题。

class A {
    public $msg;

    public function __construct() {
        $this->msg = 'foo';
    }

    public function setMessage($string) {
        $this->msg = $string;
    }

    public function getMessage() {
        var_dump($this->msg); // For demo purposes
    }

    public function triggerB() {
        $b = new B;
    }
}
class B extends A {
    public function __construct() {
        parent::setMessage('bar');
    }
}

$a = new A;
$a->getMessage();
$a->triggerB();
$a->getMessage();

我得到的输出是“foo”两次,我希望它是“foo”“bar”。

有人能解释一下我做错了什么以及如何解决这个问题? 在我的实际代码中,我希望子类验证一些$ _POST值,并将结果返回给Main类。父母使用孩子进行验证。

2 个答案:

答案 0 :(得分:3)

您正在拥有对象A并创建它的实例并将其存储在全局范围内的变量$a中。然后,您将创建类B的另一个实例,并将其存储在方法$b范围内的变量triggerB()中。

如果您将参数传递给另一个班级A,则只能更改父类B的属性。

所以这样的事情应该足够了:

<?php declare(strict_types = 1);
class A {
    public $msg;

    public function __construct() {
        $this->msg = 'foo';
    }

    public function setMessage(string $string) {
        $this->msg = $string;
    }

    public function getMessage() {
        var_dump($this->msg); // For demo purposes
    }

    public function triggerB() {
        (new B($this));
    }
}
class B {
    public function __construct(A $a) {
        $a->msg = "bar";
    }
}

$a = new A;
$a->getMessage();
$a->triggerB();
$a->getMessage();

这种方法更适合于可读性和更好的依赖管理。

另一种方法:

<?php declare(strict_types = 1);
class A {
    public $msg;

    public function __construct() {
        $this->msg = 'foo';
    }

    public function setMessage(string $string) {
        $this->msg = $string;
    }

    public function getMessage() {
        var_dump($this->msg); // For demo purposes
    }

    public function triggerB() {
        $this->msg = 'bar';
    }
}
class B {
    public function __construct(A $a) {
        $a->msg = "bar";
    }
}

$a = new A;
$a->getMessage();
$a->triggerB();
$a->getMessage();

这在性能上更好,但如果你要做一些复杂的事情,第一种方法会更好。

注意:上面的代码适用于PHP7。

答案 1 :(得分:1)

您的triggerB()方法实际上没有做任何事情:

public function triggerB() {
    $b = new B;
}

您正在创建一个新对象并将其分配给$b变量。方法一结束,$b变量/对象就不复存在了。

另请注意,方法中的$b变量与全局范围中的$a变量无关,因此设置其任何属性都不会影响$a。< / p>