php手动可见性示例混淆

时间:2012-10-09 06:47:41

标签: php visibility

我对php手册中的一个例子感到困惑。这是关于可见性的。这是一个例子。

class Bar {
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }
    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}
class Foo extends Bar {
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}
$myFoo = new foo();
$myFoo->test();  
?>

http://www.php.net/manual/en/language.oop5.visibility.php

此示例输出

Bar::testPrivate 
Foo::testPublic

请你解释一下这是怎么发生的?

为什么两个testPublic()都没有被调用?

我在Bar类构造中添加了 var_dump($this) 。它打印object(Foo)[1]。我知道的是私有属性可以用同一个类调用。

然后如何调用“Bar::testPrivate”?

6 个答案:

答案 0 :(得分:6)

  

然后如何调用“Bar :: testPrivate”?

当您致电$myFoo->test()时,它会在Bar的上下文中运行代码,因为Foo类没有覆盖它。

Bar::test()内,当$this->testPrivate()被调用时,解释器将首先查看Foo,但该方法是私有的(并且无法从{{调用来自后代类的私有方法) 1}}),所以它向上一级,直到找到合适的方法;在这种情况下,这将是Bar

相反,当调用Bar::testPrivate()时,解释器会立即在$this->testPublic()中找到合适的方法并运行它。

修改

  

为什么不调用testPublic()?

运行Foo时只调用一个方法,最远的一个(就基于距基类的距离而言)。

如果$this->testPublic()还需要执行父实现,则应在该方法中编写Foo::testPublic()

答案 1 :(得分:2)

你的函数位于Bar类,你使用魔法$this指针来调用成员函数。

尝试将函数test()移动到Foo类,看看会发生什么。输出应为:

Foo::testPrivate
Foo::testPublic

在您的示例中,调用了Bar的私有函数,因为它仅适用于该类。类Foo中没有test函数,因此Bar类的测试函数无法调用它们。

然后,由于函数重载,调用了类Foo的公共函数而不是Bar

这两个类都具有该名称的功能,因此子类的功能具有重要性。

答案 2 :(得分:1)

Private并不代表你不能称之为。这意味着您只能从当前类中调用它。 Public表示您可以从任何类调用它。

要致电Bar::testPrivate,请尝试以下方法:

$Bar->testPublic();

parent::testPublic();

但是,您无法拨打$Bar->testPrivate(),因为该方法为private

答案 3 :(得分:1)

你打电话

$myFoo->test();

参见函数test

public function test() {
    $this->testPrivate();
    $this->testPublic();
}

当在Bar类的实例(包括继承的类)上调用它时,它会调用testPrivatetestPublic

这些方法在类Foo中被覆盖,这意味着使用了Foo的方法。您始终可以调用基类的方法:

// in Foo
public function testPublic() {
    parent::testPublic();
    echo "Foo::testPublic\n";
}    

Bar::testPrivate被调用,因为它是private而不会被Foo::testPrivate覆盖。

查看更多herehere

答案 4 :(得分:1)

我猜用户'omega在2093点es'(http://www.php.net/manual/en/language.oop5.visibility.php#109324)的评论是描述同样的事情。 有句说:“在父类中定义的方法不能访问从它们继承的类中定义的私有方法。但是它们可以访问受保护的。”

在你的情况下,$this方法中的Bar::test()对象属于Foo类型(你的var_dump证明了这一点)。因为Foo::testPrivate()方法是私有的,所以无法从父类Bar访问它,并且唯一可以访问的方法仍然是Bar::testPrivate()(尝试注释定义,你会得到致命的错误)。这就是为什么第一个输出是Bar::testPrivate

$this->testPublic();调用Foo::testPublic()方法,因为$this属于Foo类型,方法定义为公开。

简而言之,私有方法只能从定义它们的类中访问。它们既不能从子类也不能从父类访问。

要使子类或父类可访问该方法,请使其受到保护。例如,如果您在两个类中都保护testPrivate()方法,则会打印Foo::testPrivate Foo::testPublic

答案 5 :(得分:0)

Foo类扩展了类Bar。然后在Bar中定义函数测试。在这个函数中有两个调用。一个是公共的,一个是私人职能吧。