public function test() { // This should call C1::foo, not D1::foo $obj = new D1(); $obj->foo(); } } class D1 extends C1 { private function foo() { echo "D1::foo\n"; } } $obj = new C1(); $obj->test(); class C2 { private function foo() { echo "C2::foo\n"; } public function test() { $this->foo(); } } class D2 extends C2 { protected function foo() {