在 PHP 中从父类访问重写的受保护变量

发布于 2024-11-02 05:50:27 字数 478 浏览 0 评论 0原文


如何通过在子类中调用其 getter 方法来从父类访问重写的受保护变量?

例如:

class A{
    protected x='test';
    protected function printx(){
        echo $this->x;
    }
}

class B extends A{
    protected x='test2';

    public function printxs(){
        parent::printx();
        echo "\n";
        echo $this->x;
    }
}

$b=new B;
$b->printsx();

我期望这个打印:

test
test2

但是这个打印:

test
test

Hi
How can I access an overrided protected variable from parent class by calling its getter method in child class?

for example:

class A{
    protected x='test';
    protected function printx(){
        echo $this->x;
    }
}

class B extends A{
    protected x='test2';

    public function printxs(){
        parent::printx();
        echo "\n";
        echo $this->x;
    }
}

$b=new B;
$b->printsx();

I expect this print :

test
test2

but this prints:

test
test

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

揽清风入怀 2024-11-09 05:50:27

首先,它不打印 test\ntest,而是打印 test2\ntest2

当你对超类进行子类化时,你就是在专门化超类。在我们的示例中,我们使用 B 类专门化 A 类。通过这种专门化,我们重新定义了受保护对象变量 $this->x 的值。

当您调用超类的方法 printx() 时,我们会被要求回显 $this->x 的值,该值已在子类中重新定义为 test2,而不是测试

这是 PHP 化的代码:

<?php

class A {
    protected $x = 'test';
    protected function printx(){
        echo $this->x;
    }
}

class B extends A {
    protected $x = 'test2';

    public function printsx(){
        parent::printx();
        echo "\n";
        echo $this->x;
    }
}

$b=new B;
$b->printsx();

Firstly, it doesn't print test\ntest, it prints test2\ntest2.

When you subclass a superclass you are specialising the superclass. In our example we are specialising the A class with the B class. Through that specialisation we're redefining the value of the protected object variable $this->x.

When you call the superclass' method printx() we are asked to echo the value of $this->x which has been redefined in our subclass to be test2, not test.

Here's the code PHPified:

<?php

class A {
    protected $x = 'test';
    protected function printx(){
        echo $this->x;
    }
}

class B extends A {
    protected $x = 'test2';

    public function printsx(){
        parent::printx();
        echo "\n";
        echo $this->x;
    }
}

$b=new B;
$b->printsx();
金兰素衣 2024-11-09 05:50:27

这里不存在“父级”这样的东西:只有一个属性——一个内存槽

即使先在父类中定义了属性,然后在子类中重新定义了该属性,只要您正在使用对象的属性($this,此处),它始终是相同的属性。

There is no such thing as "parent", here : there is only one property -- one memory slot for it.

Even if there property is first defined in the parent class, and, then, re-defined in the child class, as long as you are working with the property of an object ($this, here), it's always the same property.

与君绝 2024-11-09 05:50:27

由于您的代码无法编译,因此这里有一个更新的代码:

<?php 

class A{

    protected $x='I am the value of Class A';

    public function getValueUsingAMethod() {

        return $this->x;

    }


}

class B extends A{

    protected $x='I am the value Class B';

    public function getValueUsingBMethod(){

        return $this->x;
    }

}

$anA = new A();
$aB = new B();

// Will output: B called - I am the value of Class A
echo '<br />B called - ' . $anA->getValueUsingAMethod();

// Will output: A called - I am the value Class B
echo '<br />A called - ' . $aB->getValueUsingAMethod();

// Will output: B called - I am the value Class B
    echo '<br />B called - ' . $aB->getValueUsingBMethod();

// Outputs this
//   object(B)#2 (1) { ["x":protected]=> string(22) "I am the value Class B" } 
var_dump( $aB );

看一下输出的第二行。您调用A类的方法,该方法从B类的对象实例返回值

如果通过类 B 子类化 A,并且 B 覆盖 A 范围内的变量,则 A 的所有方法(如果从 B 的实例调用)都会自动访问被覆盖的变量。

输出的最后一行描述了 B 的内部结构。如您所见,只有一个实例变量 x 可用。

为什么?

如果您覆盖 $x,则语义是“使用我的新 $x 而不是原始 $x”。

如果您确实需要访问 A 的 $x,您可能希望在 B 中创建一个不同名称的附加成员变量。

Since your code doesn't compile here's an updated one:

<?php 

class A{

    protected $x='I am the value of Class A';

    public function getValueUsingAMethod() {

        return $this->x;

    }


}

class B extends A{

    protected $x='I am the value Class B';

    public function getValueUsingBMethod(){

        return $this->x;
    }

}

$anA = new A();
$aB = new B();

// Will output: B called - I am the value of Class A
echo '<br />B called - ' . $anA->getValueUsingAMethod();

// Will output: A called - I am the value Class B
echo '<br />A called - ' . $aB->getValueUsingAMethod();

// Will output: B called - I am the value Class B
    echo '<br />B called - ' . $aB->getValueUsingBMethod();

// Outputs this
//   object(B)#2 (1) { ["x":protected]=> string(22) "I am the value Class B" } 
var_dump( $aB );

Have a look at the second line of output. You call a method a class A and the method returns the value from the object instance of class B.

If you subclass A by means of a class B and B overwrites a variable in A's scope, all of A's methods automatically access the overwritten variables if they are called from an instance of B.

The last line of output describes the internal structure of B. As you see, only a single instance variable x is available.

Why?

If you overwrite $x, the semantics is 'Use my new $x instead of the origial $x'.

If you definitely need to access A's $x, you might wish to create a differently named additional member variable in B.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文