Все дело в видимости переменных / методов.
Вы заметите, что в классе Bar
метод testPrivate()
равен private
. Это означает, что ТОЛЬКО сам по себе может получить доступ к этому методу. Нет детей.
Поэтому, когда Foo
расширяет Bar
, а затем просит запустить метод test()
, он делает две вещи:
- Он переопределяет метод
testPublic()
, потому что он публичный, и Foo
имеет право переопределить его собственной версией.
- Он вызывает
test()
на Bar
(поскольку test()
существует только на Bar()
).
testPrivate()
является не переопределенным и является частью класса, который содержит test()
. Поэтому печатается Bar::testPrivate
.
testPublic()
переопределяется и является частью класса наследования. Следовательно, Foo::testPublic
печатается.