我写了这个简单的例子来说明我的问题。我有一个Base类和Derived类。当我调用派生类的justdoit
函数时,它不调用派生类doer
函数,而是调用基类的doer
函数。
预期产出:
Base::doer
Derived::doer
实际输出:
Base::doer
Base::doer
代码:
<?
class Base {
public function justdoit() {
$this->doer();
}
private function doer() {
print "Base::doer\n";
}
}
class Derived extends Base {
private function doer() {
print "Derived::doer\n";
}
}
$b = new Base;
$b->justdoit();
$d = new Derived;
$d->justdoit();
?>
这是C ++中的相同代码示例,它可以工作:
class A {
public:
void justdoit();
private:
virtual void doit();
};
void A::justdoit() {
doit();
}
void A::doit() {
std::cout << "A::doit\n";
}
class B : public A {
private:
virtual void doit();
};
void B::doit() {
std::cout << "B::doit\n";
}
int main() {
A a;
B b;
a.justdoit();
b.justdoit();
}
输出:
A::doit
B::doit
有趣的是,如果我更改原始PHP示例并将private function
替换为protected function
,它就会开始工作:
<?
class Base {
public function justdoit() {
$this->doer();
}
protected function doer() {
print "Base::doer\n";
}
}
class Derived extends Base {
protected function doer() {
print "Derived::doer\n";
}
}
$b = new Base;
$b->justdoit();
$d = new Derived;
$d->justdoit();
?>
输出:
Base::doer
Derived::doer
有谁知道为什么PHP和C ++会产生不同的结果?为什么在PHP中将private
更改为protected
会使它产生与C ++相同的结果?
答案 0 :(得分:6)
有关PHP中的public,protected和private的详细讨论,请参阅What is the difference between public, private, and protected?。
这是我的看法:
函数justdoit
在Base
类中声明。在doer
类中声明private
Derived
时,它在Derived
类之外没有可见性,甚至在Base
类之外也没有。因此,即使在justdoit
的实例上执行Derived
,它也会执行doer
中的Base
,因为它是doer
唯一的_appInsights = JNIEnv.FindClass ("com/microsoft/applicationinsights/library/ApplicationInsights");
_methodSetup = JNIEnv.GetStaticMethodID(_appInsights, "setup",
"(Landroid/content/Context;Landroid/app/Application;Ljava/lang/String;)V");
函数是可见的。
答案 1 :(得分:3)
private
种方法只能 才能访问该类。子类可以访问protected
个方法。通过声明private function doer
你明确地说只有类的实例可以调用该函数。
答案 2 :(得分:0)
“那么它在C ++中是如何运作的呢?”
在您的C ++代码中,您正在调用该函数的派生版本。
$d = new Derived;
$d->justdoit();
当我们创建虚函数时,这段代码将在C ++中调用“justdoit()”的派生版本,而不是基类,创建了一个维护并保存覆盖函数地址的vtable,并且调用,根据您用来调用的对象的类型,调用函数。 这里,
$b = new Base;
$b->justdoit();
在这个块中,您使用的是基础对象,因此调用了基本版本。
我希望您的查询得到解答。