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() { echo "D2::foo\n"; } } class E2 extends D2 { } $obj = new E2; // This should call C2::foo, not D2::foo $obj->test(); class C3 { private function foo() { echo "C3::foo\n"; } public function test() { $this->foo(); } } class D3 extends C3 { public function foo() { echo "D3::foo\n"; } } $obj = new D3; // This should call C3::foo, not D3::foo $obj->test(); class A4 { private function foo() { echo "A4::foo\n"; } } class B4 extends A4 { public function foo() { echo "B4::foo\n"; } } class C4 { private function foo() { echo "C4::foo\n"; } public static function test($obj) { $obj->foo(); } } C4::test(new B4); class A5 { private function __construct() { } } class B5 extends A5 { public static function test() { return new A5; } } B5::test();