If I'm writing a class, when do I make a method private, versus protected? In other words, how I can know in advance that a client programmer would never ever need to override a method? In a case where it's something that has external considerations, like a database connection?
相关问题
- how to define constructor for Python's new Nam
- Keeping track of variable instances
- Object.create() bug?
- std::vector of objects / pointers / smart pointers
- Name for a method that has only side effects
相关文章
- 接口B继承接口A,但是又不添加新的方法。这样有什么意义吗?
- NameError: name 'self' is not defined, eve
- Implementation Strategies for Object Orientation
- Check if the Type of an Object is inherited from a
- When to use Interfaces in PHP
- Are default parameters bad practice in OOP?
- How to return new instance of subclass while initi
- In OOP, what is the best practice in regards to us
public
andprotected
methods form the 'interface' to your object,public
for developers using (delegating to) your class, andprotected
for developers wishing to extend the functionality of your object by subclassing it.Note that it's not necessary to provide
protected
methods, even if your class will be subclassed.Both
public
andprotected
interfaces need careful thought, especially if this is an API to be used by developers outside your control, since changes to the interface can break programs that make assumptions about how the existing interface works.private
methods are purely for the the author of the object, and may be refactored, changed and deleted at will.I would go for
private
by default, and if you find you need to expose more methods, have a careful think about how they will be used - especially if they are virtual–what happens if they are replaced completely with an arbitrary alternative function by another developer–will your class still work? Then design some appropriateprotected
which are useful for developers subclassing your object (if necessary), rather than exposing existing functions.I typically just make everything
private
and refactor when I need to call it from a base class.Except when I feel lazy and do everything
protected
that isn't definitely dangerous.You cannot. And you don't need to. It is not your job to anticipate IF a developer might want to override a method, let alone how. Just assume he wants to and enable him to do so without having to touch your code. And for this reason, do not declare methods
private
if you don't have to.If a developer feels he needs to adjust some functionality of your classes, he can pick from a number of structural and behavioral patterns to do so, e.g. Decorators, Adapters or by subclassing. Using these patterns is good, because it encapsulates the changes into the developer's own class and leaves your own code untouched. By declaring methods
private
, you make sure the developer will monkey with your class. And that is bad.A perfect example is Zend Framework's DB adapter. They discourage the use of persistent connections and their adapters provide no mean to this end. But what if you'd want to have this nonetheless and the adapter method was marked
private
(it isn't, but what if)? Since there is no way to overwrite the method, you would (yes, you would) change the adapter code right within it's class or you'd copy & paste the code into your own adapter class, effectively duplicating 99% of the class just to change a single function call. Whenever there is an update to this adapter, you either would lose your changes or you wouldn't get it (in case you c&p'd). Had it been markedprotected
(as it is), you could just have written a pConnectAdapter subclass.Moreover, when subclassing, you are effectively saying subClass is a parentClass. Thus, you can expect the derived class to have the same functionality as the parentClass. If there is functionality in the parentClass that should not be available in the subClass, then disabling it conceptually belongs to the subClass.
This is why I find it much better practise to default all methods and properties to
protected
visibility and only mark those methods (not properties though) supposed to allow interaction with my class from another class or script aspublic
, but only a few thingsprivate
. This way, I give the developer the choice of using my class as I intended it to be used and the option to tweak it. And if he breaks something in the process, it is very likely his fault then, not mine.Update: since I wrote this four years ago I have come to the conclusion that defaulting things to protected instead of private often leads to suboptimal subclasses. This is because people will start to use whatever you provided as protected. This in turn means you have to consider all these methods as API and may not change them at will. As such, it's better to carefully consider what extensions points you want to provide and keep the everything else private. See http://fabien.potencier.org/article/47/pragmatism-over-theory-protected-vs-private for a similar view.
Don't think of the private/protected/public thing as if a programmer would ever "need" a method. Think of it as if you want to allow them access to it.
If you think they should be allowed to change the DB Connection String then make it public.
I typically will start at the lowest level. If you're unsure make it private. Then as needed you can make things protected or public.
The idea being it is not a breaking change to go from private to protected but it could be a breaking change to go the other way.
Private members are used to encapsulate the inner workings of your class. Use them to hold data that only you want to be able to access. For example, let's say you have a field called _name and a getter/setter named GetName()/SetName(name). Maybe you want to do some syntax checking on name before you allow the SetName to succeed, else you throw an exception. By making _name private, you ensure that this syntax checking will occur before any changes to name can occur (unless you yourself change _name in your own class, in your own code). By making it protected, you're saying to any potential future inheritor of your class, "go ahead and monkey with my field."
In general, protected is used sparingly and only in specialized cases. For example, you might have a protected constructor that exposes some additional construction functionality to child classes.