-4

I wrote this simple example that demonstrates my problem. I've a Base class and Derived class. When I call derived class's justdoit function, it doesn't call derived class doer function, instead it calls base class's doer function.

Expected output:

Base::doer
Derived::doer

Actual output:

Base::doer
Base::doer

Code:

<?

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();

?>

Here's this same code example in C++ and it works:

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();
}

Output:

A::doit
B::doit

Funny thing is if I change my original PHP example and replace private function with protected function it starts working:

<?

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();

?>

Output:

Base::doer
Derived::doer

Does anyone know why PHP and C++ produce different results and why does changing private to protected in PHP makes it produce the same result as C++?

bodacydo
  • 75,521
  • 93
  • 229
  • 319

3 Answers3

6

See What is the difference between public, private, and protected? for a good discussion of public, protected, and private in PHP.

Here's my take:

The function justdoit is declared in the Base class. When doer is declared private in the Derived class, it has no visibility outside the Derived class, not even to the Base class. Hence, even though justdoit is executed on an instance of Derived, it executes the doer in Base because that's the only doer function that is visible to it.

Community
  • 1
  • 1
schtever
  • 3,210
  • 16
  • 25
  • Then how come it works in C++ where it's also private? How come the same OOP code example produces two different results in two different languages. – bodacydo Jul 19 '15 at 23:30
  • Your use of `virtual` might explain it. As I understand it, when you declare a function `virtual` in C++, you're instructing the language to use the most derived function that matches the signature. – schtever Jul 20 '15 at 00:16
  • That could explain it. Do you know how to make virtual function in PHP for same effect? – bodacydo Jul 20 '15 at 02:16
3

private methods can only be access by that class. protected methods can be access by child classes. By declaring private function doer you explicitly saying only instances of class can call that function.

Similar Question

Community
  • 1
  • 1
Victory
  • 5,811
  • 2
  • 26
  • 45
0

"Then how come it works in C++ where it's also private?"

Here in your C++ code you are calling the derived version of the function.

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

This code will call the derived version of the "justdoit()", not the base,in C++ when we create virtual functions, a vtable is created which maintains and holds the address of the overwritten functions, and at the time of calling, based on the type of the object you are using to call, functions gets invoked. Here,

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

in this block, you are using base object, hence base version got called.

I hope your query got answered.

Nishant
  • 1,635
  • 1
  • 11
  • 24