Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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 oop行为,有人能解释一下吗?_Php_Oop_Inheritance - Fatal编程技术网

奇怪的php oop行为,有人能解释一下吗?

奇怪的php oop行为,有人能解释一下吗?,php,oop,inheritance,Php,Oop,Inheritance,简而言之:类从其父类继承函数。然后在子类上调用此函数,但似乎仍具有父类的作用域。这是预期的行为吗 考虑以下代码示例: <?php class OLTest { private $var1 = 10; public function getVar1() { if (isset($this->var1)) { return $this->var1; } else { return 'u

简而言之:类从其父类继承函数。然后在子类上调用此函数,但似乎仍具有父类的作用域。这是预期的行为吗

考虑以下代码示例:

<?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
10
calling child->getVar2
undefined
更让人困惑的是,两个函数中的一个
print\r($this)
将显示作用域确实设置为子类,但不可能访问变量

有人能帮我澄清一下吗

编辑:我在5.3.3-1ubuntu9.5版本中使用PHP。

您不能将
private$var2
注入父类,这正是您试图做的。
所以是的,这是正常的行为。

它似乎与
私有范围相关


尝试更改为
受保护
公共
并检查结果。

因为您已将变量声明为私有,所以它们彼此完全隐藏。因此,父对象中的
$var1
实际上是与子对象中的
$var1
不同的变量

在父级上调用
getVar1
时,它使用它看到的
$var1
,即来自父级的值为10的值。类似地,父级无法看到子级的
$var2
,因此该属性未定义


当您对子对象调用
getVar1
getVar2
时,这些方法本身从父类继承而来,其行为与从类型为OLTest的对象调用它们时的行为完全相同。是的,这是因为您的属性是私有的。您正在调用的方法仍然属于父类,因为您尚未重新定义它们。若要启用访问子属性的父方法,必须在父类和子类中使它们受到保护:

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;
}
如果将其保持在父类中,则不允许子类重写该属性,因此属于父类的函数将访问其自己的私有属性。若在子类中将其设为私有,则不允许父方法访问它


如果您仍然想将它们保持私有,您必须将方法的粘贴代码复制到子类中(是的,
返回parent::getVar1()
也不起作用)。

否,输出应明确为
10,未定义,10,未定义。
原因是
private
的变量仅对定义它们的类可见(而不是超级类或子类)

因此,当调用
child
时,它的方法在父对象中定义,当它们解析
var1
var2
时,它们检查为
OLTest
定义的范围。
var2
也无法访问,因为声明的
var2
仅在
OLTest2
内部可见


要获得输出,您应该声明这些变量
protected
public

这是您的私有变量的范围,请尝试使用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

忘了吧。它的5.3.3.1作为检查isset和返回值或取消定义的简单方法添加更改变量范围修复了这一问题。但是继承的方法不应该首先在子类的范围内执行吗?似乎该方法在“类内”而不是“实例内”运行。在这种情况下,“OLTest”(类)看不到“var2”,只能看到自己的“var1”,即使“$oltest2”(实例)是一个“oltest2”对象……那么,当我将变量范围更改为protected时,它是如何按预期工作的呢?好的,谢谢。似乎我需要更新一下我的oop:)我知道这是PHP团队的oop实现决策,而不是一个绝对的oop规则。也许我错了,但我就是这么看的。
calling parent->getVar1
10
calling parent->getVar2
undefined
calling child->getVar1
11
calling child->getVar2
20