private
and protected
are there to make it easier to write code that does the right thing. As you've noticed, they're not unbreakable -- there's nothing preventing you from bypassing them if you want to. That's because they're meant to protect you from accidentally doing the wrong thing, not from actively trying to.
That you can bypass them with reflection, doesn't mean you should. You can consider private
and protected
as kinda a "warranty void if broken" sticker; if you ignore them and muck around with stuff yourself directly, the object/class might not behave properly. It has no obligation to at that point, since you've taken it upon yourself to mess with its innards -- and the code that does so is entirely to blame.
Now, as for the question in the title...you use protected
to declare the interface specifically for subclasses; you basically declare that you intend for them to use that stuff directly, while private
says that you don't. Whether they disregard that is up to them, but if they do, then screw 'em. You tried to warn them.