Private vs Protected

I've been searching and I know the theoretic difference.

  • public - Any class/function may access the method/property.
  • protected - Only this class and any subclasses may access the method/property.
  • private - Only this class may access the method/property. It won't even be inherited.
  • That's all fine and well, the question is, what's the practical difference between them? When would you use private and when would you use protected ? Is there a standard or acceptable good practice over this one?

    Up until now, to retain the concept of inheritance and polymorphism, I use public for anything that should be accessed from the outside (like constructors and main class functionality), and protected for internal methods (logic, helper methods etc). Am I on the right track?

    (Note that this question is for me, but also for future reference as I haven't seen a question like this one SO).


    No, you're not on the right track. A good rule of thumb is: make everything as private as possible. This makes your class more encapsulated, and allows for changing the internals of the class without affecting the code using your class.

    If you design your class to be inheritable, then carefully choose what may be overridden and accessible from subclasses, and make that protected (and final, talking of Java, if you want to make it accessible but not overridable). But be aware that, as soon as you accept to have subclasses of your class, and there is a protected field or method, this field or method is part of the public API of the class, and may not be changed later without breaking subclasses.

    A class that is not intended to be inherited should be made final (in Java). You might relax some access rules (private to protected, final to non-final) for the sake of unit-testing, but then document it, and make it clear that although the method is protected, it's not supposed to be overridden.


    Let me preface this by saying I'm talking primarily about method access here, and to a slightly lesser extent, marking classes final, not member access.

    The old wisdom

    "mark it private unless you have a good reason not to"

    made sense in days when it was written, before open source dominated the developer library space and VCS/dependency mgmt. became hyper collaborative thanks to Github, Maven, etc. Back then there was also money to be made by constraining the way(s) in which a library could be utilized. I spent probably the first 8 or 9 years of my career strictly adhering to this "best practice".

    Today, I believe it to be bad advice. Sometimes there's a reasonable argument to mark a method private, or a class final but it's exceedingly rare, and even then it's probably not improving anything.

    Have you ever:

  • Been disappointed / surprised / hurt by a library etc. that had a bug that could have been fixed with inheritance and few lines of code, but was forced to wait for an official patch due to private / final methods & classes?
  • Wanted to use a library for a slightly different use case than was imagined by the authors but was unable to do so due to private / final methods & classes?
  • Been disappointed / surprised / hurt by a library etc. that was overly permissive in it's extensibility?
  • These are the three biggest rationalizations I've heard for marking methods private by default:

    Rationalization #1: It's unsafe and there's no imaginable reason to override a specific method

    I can't count the number of times I've been wrong about whether or not there will ever be a need to override a specific method I've written. Having worked on several popular open source libs, I've learned the hard way the true cost of marking things private. It often eliminates the only practical solution to unforseen problems or use cases. Conversely, I've never in 16+ years of professional development regretted marking a method protected instead of private for reasons related to API safety. When a developer chooses to extend a class and override a method, they are consciously saying "I know what I'm doing." and for the sake of productivity that should be enough. period. If it's dangerous, note it in the class/method Javadocs, don't just blindly slam the door shut.

    Marking methods protected by default is a mitigation for one of the major issues in modern SW development: failure of imagination.

    Rationalization #2: It keeps the public API / Javadocs clean

    This one is actually pretty reasonable, and depending on the target audience it might even be the right thing to do, but it's worth considering what the cost of keeping the API "clean" actually is: extensibility. For the reasons mentioned above, it might still make sense to mark things protected by default just in case.

    Rationalization #3: My software is commercial and I need to restrict it's use.

    This one's actually pretty reasonable. As a consumer though I'd go with the less restrictive competitor (assuming no significant quality differences exist) every single time.

    Never say never

    I'm not saying never mark methods private. I'm asserting that a better rule of thumb is to "make methods protected unless there's a good reason not to".

    This advice is best suited for those working on libraries or larger scale projects that have been broken into modules. For smaller or more monolithic projects it doesn't tend to matter as much since you control all the code anyway and it's easy to change the access level of your code if/when you need it. Even then though, I'd still give the same advice :-)


    I read an article a while ago that talked about locking down every class as much as possible. Make everything final and private unless you have an immediate need to expose some data or functionality to the outside world. It's always easy to expand the scope to be more permissible later on, but not the other way around. First consider making as many things as possible final which will make choosing between private and protected much easier.

  • Make all classes final unless you need to subclass them right away.
  • Make all methods final unless you need to subclass and override them right away.
  • Make all method parameters final unless you need to change them within the body of the method, which is kinda awkward most of the times anyways.
  • Now if you're left with a final class, then make everything private unless something is absolutely needed by the world - make that public.

    If you're left with a class that does have subclass(es), then carefully examine every property and method. First consider if you even want to expose that property/method to subclasses. If you do, then consider whether a subclass can wreak havoc on your object if it messed up the property value or method implementation in the process of overriding. If it's possible, and you want to protect your class' property/method even from subclasses (sounds ironic, I know), then make it private. Otherwise make it protected.

    Disclaimer: I don't program much in Java :)

    链接地址: http://www.djcxy.com/p/31494.html

    上一篇: 在C#getter中使用StringBuilder会特别糟糕吗?

    下一篇: 私人与受保护