Can someone please explain to me under what situations "protected" is not just a variant of "public"? Any time you can inherit from the class, if you want access to its members you simply create a new subclass and access anything protected. If you can't inherit from the class (because it's package-private, for example) protected members serve no clear purpose. I've always felt that a language could get away with just package-private and public, so it's been nice to see so many modern languages embracing that.
Ok, let's say you have a class that performs some process - ProcessBase. It then needs to call Step1(), Step2(), and Step3() methods. I had a similar case a few months ago at work.
However in certain cases, you need to change what Step2() is, but not break up the process. You don't want outside callers to access Step2() directly, but you need a way to allow a subclass to define it's own Step2() while keeping the overall process intact.
So you would make those three methods protected (and, depending on language, virtual) and override as needed in a subclass.
That's the use case I've used protected for.
Also, I may want to do things internally inside my package/module/library that I want to be able to internally override, but not make it part of my API in case I want to change it later.
Here's what I don't understand: either you need to modify it within its own package (so you can use package-private to prevent anyone else from accessing it) or you have to leave it available for potentially anyone to modify, as you already are when you make it protected (hence: public). To be clear, I understand why people want protected. I'm just not sure it's strictly necessary from a permissions / invariants standpoint.
(Conversely, your scenario can be precisely solved without violating encapsulation by passing in step2 as a function, and passing in any information it requires as parameters. I suspect most of the usecases for protected go away with first-class functions).