简而言之:一个类从其父级继承一个函数。然后在子项上调用此函数,但似乎仍具有父类的范围。这是预期的行为吗?
请考虑以下代码示例:
<?php
class OLTest {
private $var1 = 10;
public function getVar1() {
if (isset($this->var1)) {
return $this->var1;
} else {
return 'undefined';
}
}
public function getVar2() {
if (isset($this->var2)) {
return $this->var2;
} else {
return 'undefined';
}
}
}
class OLTest2 extends OLTest {
private $var1 = 11;
private $var2 = 20;
}
$oltest = new OLTest();
$oltest2 = new OLTest2();
echo "calling parent->getVar1\n";
echo $oltest->getVar1() . "\n";
echo "calling parent->getVar2\n";
echo $oltest->getVar2() . "\n";
echo "calling child->getVar1\n";
echo $oltest2->getVar1() . "\n";
echo "calling child->getVar2\n";
echo $oltest2->getVar2() . "\n";
?>
根据我的理解,输出应为:
calling parent->getVar1
10
calling parent->getVar2
undefined
calling child->getVar1
11
calling child->getVar2
20
我机器上的实际输出是:
calling parent->getVar1
10
calling parent->getVar2
undefined
calling child->getVar1
10
calling child->getVar2
undefined
为了增加混淆,任何一个函数中的print_r($this)
都会显示范围确实设置为子类,但是无法访问变量。
有人可以为我清楚吗?
编辑:我在版本5.3.3-1ubuntu9.5中使用PHP。
答案 0 :(得分:4)
不,输出应该是10, undefined, 10, undefined
。
原因是private
变量只对定义它们的类(不是超类或子类)可见。
因此,当调用child
时,其方法在父对象中定义,当他们解析var1
或var2
时,他们会检查为OLTest
定义的范围。
var2
也无法访问,因为声明的var2
仅在OLTest2
内可见。
要获得输出,您应该声明这些变量protected
或public
。
答案 1 :(得分:2)
它似乎与private
范围相关。
尝试更改为protected
或public
并检查结果。
答案 2 :(得分:2)
是的,这是因为您的属性是私有的。您正在调用的方法仍属于父类,因为您尚未重新定义它们。要启用访问子属性的父方法,必须在父类和子类中使它们protected
:
class OLTest {
protected $var1 = 10;
public function getVar1() {
if (isset($this->var1)) {
return $this->var1;
} else {
return 'undefined';
}
}
public function getVar2() {
if (isset($this->var2)) {
return $this->var2;
} else {
return 'undefined';
}
}
}
class OLTest2 extends OLTest {
protected $var1 = 11;
protected $var2 = 20;
}
如果将它private
保留在父类中,它将不允许子类覆盖该属性,因此属于父类的函数将访问其自己的私有属性。如果你在子类中将其设为私有,则不允许父方法访问它。
如果您仍想将它们保密,则必须将方法的代码复制粘贴到子类中(是的,return parent::getVar1()
也不会有效。)
答案 3 :(得分:1)
您不能将private $var2
“注入”父类,这是您尝试做的事情。
所以是的,这是正常行为。
答案 4 :(得分:1)
因为您已将您的vars声明为私有,所以它们彼此完全隐藏。因此,父级中的$var1
实际上是与子级中的$var1
不同的变量
当您在父级上调用getVar1
时,它会使用它看到的$var1
,父级的值为10.同样,父级无法看到孩子的$var2
,所以财产未定义。
当您在子节点上调用getVar1
和getVar2
时,方法本身将从父类继承,并且行为与从OLTest类型的对象调用它们时的行为完全相同
答案 5 :(得分:0)
这是私有变量的范围,请尝试使用protected
class OLTest {
protected $var1 = 10;
public function getVar1() {
return isset($this->var1) ? $this->var1:'undefined';
}
public function getVar2() {
return isset($this->var2) ? $this->var2:'undefined';
}
}
class OLTest2 extends OLTest {
protected $var1 = 11;
protected $var2 = 20;
}
$oltest = new OLTest();
$oltest2 = new OLTest2();
echo "calling parent->getVar1\n".$oltest->getVar1()."\n";
echo "calling parent->getVar2\n".$oltest->getVar2()."\n";
echo "calling child->getVar1\n".$oltest2->getVar1()."\n";
echo "calling child->getVar2\n".$oltest2->getVar2()."\n";
结果:
calling parent->getVar1
10
calling parent->getVar2
undefined
calling child->getVar1
11
calling child->getVar2
20