为什么在PHP中不通过base调用派生类的函数?

时间:2015-07-19 23:01:27

标签: php c++ oop inheritance private

我写了这个简单的例子来说明我的问题。我有一个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 ++相同的结果?

3 个答案:

答案 0 :(得分:6)

有关PHP中的public,protected和private的详细讨论,请参阅What is the difference between public, private, and protected?

这是我的看法:

函数justdoitBase类中声明。在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你明确地说只有类的实例可以调用该函数。

Similar Question

答案 2 :(得分:0)

“那么它在C ++中是如何运作的呢?”

在您的C ++代码中,您正在调用该函数的派生版本。

$d = new Derived;
$d->justdoit();

当我们创建虚函数时,这段代码将在C ++中调用“justdoit()”的派生版本,而不是基类,创建了一个维护并保存覆盖函数地址的vtable,并且调用,根据您用来调用的对象的类型,调用函数。 这里,

$b = new Base;
$b->justdoit();

在这个块中,您使用的是基础对象,因此调用了基本版本。

我希望您的查询得到解答。