Reasons to use private instead of protected for fields and methods

Silvio Donnini picture Silvio Donnini · Feb 6, 2011 · Viewed 11.8k times · Source

This is a rather basic OO question, but one that's been bugging me for some time.

I tend to avoid using the 'private' visibility modifier for my fields and methods in favor of protected.

This is because, generally, I don't see any use in hiding the implementation between base class and child class, except when I want to set specific guidelines for the extension of my classes (i.e. in frameworks). For the majority of cases I think trying to limit how my class will be extended either by me or by other users is not beneficial.

But, for the majority of people, the private modifier is usually the default choice when defining a non-public field/method.

So, can you list use cases for private? Is there a major reason for always using private? Or do you also think it's overused?

Answer

Macke picture Macke · Feb 6, 2011

There is some consensus that one should prefer composition over inheritance in OOP. There are several reasons for this (google if you're interested), but the main part is that:

  • inheritance is seldom the best tool and is not as flexible as other solutions
  • the protected members/fields form an interface towards your subclasses
  • interfaces (and assumptions about their future use) are tricky to get right and document properly

Therefore, if you choose to make your class inheritable, you should do so conciously and with all the pros and cons in mind.

Hence, it's better not to make the class inheritable and instead make sure it's as flexible as possible (and no more) by using other means.

This is mostly obvious in larger frameworks where your class's usage is beyond your control. For your own little app, you won't notice this as much, but it (inheritance-by-default) will bite you in the behind sooner or later if you're not careful.

Alternatives

Composition means that you'd expose customizability through explicit (fully abstract) interfaces (virtual or template-based).

So, instead of having an Vehicle base class with a virtual drive() function (along with everything else, such as an integer for price, etc.), you'd have a Vehicle class taking a Motor interface object, and that Motor interface only exposes the drive() function. Now you can add and re-use any sort of motor anywhere (more or less. :).