6

我对 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()都不叫?

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

那么“ Bar::testPrivate”怎么称呼呢?

4

6 回答 6

6

那么如何调用“Bar::testPrivate”呢?

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

在内部Bar::test(),当$this->testPrivate()被调用时,解释器会Foo首先查看,但该方法是私有的(并且不能从后代类调用私有方法Bar),因此它会向上一层,直到找到合适的方法;在这种情况下,那将是Bar::testPrivate()

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

编辑

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

运行时只调用一种方法$this->testPublic(),即最远的一种(就与基类的距离而言)。

如果Foo::testPublic()还需要执行父级的实现,你应该parent::testPublic()在那个方法里面写。

于 2012-10-09T06:56:45.287 回答
2

您的函数位于Bar类中,并且您正在使用魔术$this指针来调用成员函数。

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

Foo::testPrivate
Foo::testPublic

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

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

这两个类都有一个同名的函数,所以子类的函数很重要。

于 2012-10-09T06:57:12.230 回答
1

Private并不意味着你不能调用它。这意味着您只能从当前类调用它。Public意味着您可以从任何类调用它。

要打电话Bar::testPrivate,试试这个:

$Bar->testPublic();

或者

parent::testPublic();

但是,您不能调用$Bar->testPrivate(),因为方法是private.

于 2012-10-09T06:51:32.857 回答
1

你打电话

$myFoo->test();

见功能test

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

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

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

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

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

在此处此处查看更多信息。

于 2012-10-09T06:57:26.557 回答
1

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

在您的情况下,方法中的$this对象是类型(您的 var_dump 证明了这一点)。因为方法是私有的,所以不能从父类 Bar 访问,只能访问的方法仍然存在(尝试注释定义,会出现致命错误)。这就是为什么第一个输出是.Bar::test()FooFoo::testPrivate()Bar::testPrivate()Bar::testPrivate

该行$this->testPublic();调用Foo::testPublic()方法,因为$this它的Foo类型和方法被定义为公共的。

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

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

于 2012-10-09T07:05:56.003 回答
0

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

于 2012-10-09T06:57:57.737 回答