TL;DR The answer you linked makes a few too many assumption, in my opinion, about a cherrypicked scenario where something is already going wrong. Your interpretation, based on the question you posted here, is mainly focused on scenarios that are polar opposites of the scenarios that the original answer focused on, which is why you're not seeing a lot of agreement between their stance and yours.
Realistically, it's contextual. It depends on what kind of scenario you find yourself in. But for the purpose of defining a generalized good practice guideline (as opposed to a specific targeted feedback to a specific group of devs), I align myself with your stance more than that of the previous answer's.
Part of this is a clash of definitions.
If I see a protected variable, my inference is that the designer of the base class exposed it there for me to use (if I need to). But the answer's first bullet point:
- They tend to lead to YAGNI issues. Unless you have a descendant class that actually does stuff with the protected member, make it private.
... interprets it differently. They're arguing a scenario where exposing the variable (by making it protected) was done without consideration that a derived class would make use of it.
The issue here is one of context. If the base class has not been designed to account for how any derived classes intend to alter it, yeah then the base class should not be exposing variables which allow derived classes to alter how it works.
At the same time, if a base class has already considered (as part of its design) how to allow derived classes to alter it, then it invariably needs to expose this access via protected members (fields/properties/method as is appropriate).
Which brings us to the second bullet point in the answer:
- They tend to lead to LSP issues. Protected variables generally have some intrinsic invariance associated with them (or else they'd be public). Inheritors then need to maintain those properties, which people can screw up or willfully violate.
... and again, the interpretation made by the answerer is that things were made protected before/without considering if and how they should be used by deriving classes; which in my opinion makes little sense.
However, that's not to say that "don't expose what you're not ready to handle yet" doesn't make sense. I've worked in teams where the vast majority were inexperienced juniors and they needed to be told this information.
But as far as mid-level (or above) developers are concerned, this advice seems trivial, and the second bullet point seems to operate from an assumption that the preceding developer exposed things that they were not able to have altered by outside sources, which amounts to pointing out a rookie mistake, not providing an advanced development guideline for non-rookies.
Third bullet point:
- They tend to violate OCP. If the base class makes too many assumptions about the protected member, or the inheritor is too flexible with the behavior of the class, it can lead to the base class' behavior being modified by that extension.
... is in my opinion irrelevant. I don't mean that the opinion is wrong, I mean that it's just on another topic entirely. Whether or not a member should be made protected is a completely different question from judging how a base class could potentially have implemented any logic surrounding that member in a less-than-ideal way.
Not making members protected is not going to stop an OCP-violation-creating developer from creating OCP violations in their code. They're just two completely unrelated considerations.
Fourth bullet point:
- They tend to lead to inheritance for extension rather than composition. This tends to lead to tighter coupling, more violations of SRP, more difficult testing, and a slew of other things that fall within the 'favor composition over inheritance' discussion.
... is not very wrong in the sense that relying on protected access modifier inherently means relying on inheritance, and there is a general shift towards composition over inheritance.
However, we again strike on that same kind of different interpretation. Yes, it's correct to say that a developer should consider composition over inheritance. No, that does not mean that you should never use inheritance. And no, therefore it also does not mean that there is never a scenario to use the protected access modifier.
On the premise that inheritance is the right call in a scenario, there is nothing wrong with then using protected members where appropriate. The fourth bullet point's assumption that protected access modifiers are a gateway drug to overuse of inheritance is again, in my opinion, nonsensical.
But it would be unfair for me to omit the closing sentiment of that answer:
But as you see, all of these are 'tend to'. Sometimes a protected member is the most elegant solution. And protected functions tend to have fewer of these issues. But there are a number of things that cause them to be treated with care. With anything that requires that sort of care, people will make mistakes and in the programming world that means bugs and design problems.
... because they are right here, things are contextual and there are cases where it is the right approach, and cases where it is the wrong approach.
The part of the answer I disagree with is the interpretation that the use of the protected access modifier was executed before considering that it was a good call to give derived classes access to this member and considering if inheritance was even right in the first place.
In my opinion, that is a nonsensical interpretation in most cases. This may be good advice for specific developers who are making that specific mistake of exposing things before evaluating their design; but I don't think it's a productive basis for a broader good practice guideline, which is what that answer is intending to establish.