gpt4 book ai didi

php - 公共(public)/ protected 类属性不会覆盖父类的私有(private)属性?

转载 作者:行者123 更新时间:2023-12-04 14:24:39 33 4
gpt4 key购买 nike

在 Parent 类上声明一个私有(private)属性,然后在 Child 类上将该属性重新声明为 public 或 protected。

当您创建 Child 类的实例并调用从 Parent 类继承的方法时。使用父类的属性,而不是子类的属性。

如果父类上属性的初始声明是公共(public)的或 protected ,则不是这种情况。

谁能给我解释一下这是为什么?

<?php

class P {
private $foo = 'bar';

public function e()
{
echo get_class($this);
echo "\n";
echo $this->foo;
echo "\n";
}
}

class C extends P
{
protected $foo = 'baz';
}

$parent = new P();
$child = new C();

$parent->e();
$child->e();

Output:
P
bar
C
bar

Expected Output:
P
bar
C
baz

最佳答案

私有(private)属性,顾名思义,就是私有(private)的。这意味着它们只能从类中访问。正如其他人在评论中提到的,this question对 PHP 中的变量作用域提供了非常深入的解释,所以一定要去看看,这是一本有趣的读物。

然而,在您的具体情况下,您似乎担心在子类中重命名/重载变量。更具体地说,我们正在研究当父类和子类碰巧都具有同名属性并且父类具有返回该属性的函数时会发生什么。

class A {
private $foo = 'bar';

public function getFoo() {
return $this->foo;
}
}

class B extends A {
protected $foo = 'something something';
}

$b = new B;

echo $b->getFoo();

在上面的示例中,输出将是 bar,这实际上是预期的行为。由于 getFoo 函数在子类中没有被覆盖,PHP 在父类中执行该函数。当它到达那里时,$this 引用 A,因此打印 $foo 的值,因为它在 A 。值得注意的是,在此特定示例中,B::foo 的范围并不重要。事实上,它可以完全省略,代码仍然可以完美运行。

我们可以尝试不同的函数作用域,看看会发生什么:

class A {
private $foo = 'bar';

public function getFoo() {
return $this->foo;
}

private function getCapitalizedFoo() {
return strtoupper($this->foo);
}

protected function getDoubleFoo() {
return $this->foo . $this->foo;
}
}

class B extends A {
protected $foo = 'something something';

public function getParentDoubleFoo() {
return parent::getDoubleFoo();
}
}

$b = new B;

echo $b->getFoo().PHP_EOL; // Output: bar
echo $b->getParentDoubleFoo(); // Output: barbar
echo $b->getDoubleFoo(); // Output: Uncaught Error: Call to protected method ...
echo $b->getCapitalizedFoo(); // Output: Uncaught Error: Call to private method ...

现在,问题仍然存在:如何从父类访问私有(private)成员?

如果你读过这个主题,你可能知道,除非完全必要,否则你的对象的属性应该是私有(private)的,以便尽可能多地封装它的逻辑和数据。知道这一点,允许子类访问和修改其父类属性的最佳方法是为它们创建访问器和修改器。

class A {
private $foo = 'foo';
private $bar = 'bar';

public function setFoo($foo) {
$this->foo = $foo;
}

public function getFoo() {
return $this->foo;
}

protected function setBar($bar) {
$this->bar = $bar;
}

protected function getBar() {
return $this->bar;
}
}

class B extends A {
public function __construct() {
parent::setFoo('more foo');
parent::setBar('more bar');
}

public function getCapitalizedFoo() {
return strtoupper(parent::getFoo());
}

public function getCapitalizedBar() {
return strtoupper(parent::getBar());
}
}

$b = new B;

echo $b->getCapitalizedFoo(); // Output: MORE FOO
echo strtoupper($b->getFoo()); // Output: MORE FOO
echo $b->getCapitalizedBar(); // Output: MORE BAR
echo strtoupper($b->getBar()); // Output: Uncaught Error: Call to protected method ...

通过创建公共(public)函数来访问和修改父类的属性,您允许子类覆盖它们并执行自己的逻辑,而无需复制变量。然而,这也意味着 B 的任何实例都可能改变 A 中定义的值。为了缓解这种情况,您可以创建 protected 函数,允许 B 在内部访问和使用父类属性,但是使用 B 的代码将无法做同样的事情。

关于php - 公共(public)/ protected 类属性不会覆盖父类的私有(private)属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48330224/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com