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

Why doesn't derived class's function get called through base in PHP?

本文关键字:base 调用 派生 函数 PHP 为什么      更新时间:2023-10-16

我写了一个简单的例子来演示我的问题。我有一个基类和派生类。当我调用派生类的justdoit函数时,它不调用派生类doer函数,而是调用基类的doer函数。

预期输出:

Base::doer
Derived::doer

实际输出:

Base::doer
Base::doer

代码:

<?
class Base {
 public function justdoit() {
  $this->doer();
 }
 private function doer() {
  print "Base::doern";
 }
}
class Derived extends Base {
 private function doer() {
  print "Derived::doern";
 }
}
$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::doitn";
}
class B : public A {
    private:
        virtual void doit();
};
void B::doit() {
    std::cout << "B::doitn";
}
int main() {
 A a;
 B b;
 a.justdoit();
 b.justdoit();
}

输出:

A::doit
B::doit

有趣的是,如果我改变我原来的PHP示例,用protected function替换private function,它就会开始工作:

<?
class Base {
 public function justdoit() {
  $this->doer();
 }
 protected function doer() {
  print "Base::doern";
 }
}
class Derived extends Base {
 protected function doer() {
  print "Derived::doern";
 }
}
$b = new Base;
$b->justdoit();
$d = new Derived;
$d->justdoit();
?>

输出:

Base::doer
Derived::doer

有人知道为什么PHP和C++会产生不同的结果吗?为什么在PHP中将private更改为protected会产生与C++相同的结果?

查看公共、私有和受保护之间的区别是什么?以便在PHP中很好地讨论公共、受保护和私有。

这是我的看法:

函数justdoit是在Base类中声明的。当doerDerived类中声明为private时,它在Derived类之外没有可见性,甚至对Base类也没有可见性。因此,即使在Derived的实例上执行justdoit,它也会在Base中执行doer,因为这是它唯一可见的doer函数

private方法只能被该类访问protected方法可以由子类访问。通过声明private function doer,您明确表示只有类的实例才能调用该函数。

类似问题

"那么它在C++中是如何工作的呢?">

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

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

这段代码将调用C++中"justdoit(("的派生版本,而不是基函数。当我们创建虚拟函数时,会创建一个vtable,用于维护和保存被覆盖函数的地址。在调用时,根据要调用的对象的类型,会调用函数。这里,

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

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

我希望你的问题得到答复。