Reputation: 18848
In a lot of my PHP projects, I end up with classes that have non-public functions that I don't intend to extend.
Is it best to declare these as protected, or private?
I can see arguments both ways - making them private is a far more conservative approach, but it can be argued that they could be made protected later if I want the method to be extended and it makes it clear which methods are extended by base classes.
On the other hand, is using private somehow antisocial, in that it impedes a theoretical future developer from extending my code without modification?
Upvotes: 37
Views: 7713
Reputation: 108
As said, if you are going to extend a class later you can always change it then.
But if you can avoid to use inheritance you should. It is better to use other patterns when designing, if possible.
Basically what to do is favor composition over inheritance and program to interfaces, not to implementations.
If you let classes just have one tightly defined purpose than you can composit objects instead of letting them inherit each other. If you use interfaces rather then inheritance you will most likely define small and effective interfaces. Then you will see that inheritance will reduce and therefore the need for "protected" will reduce too.
Example
interface sound {
public function makeSound();
}
class bark implements sound{
public function makeSound() {
return "Bark!!!";
}
}
class meow implements sound{
public function makeSound() {
return "Meowmeow!!!";
}
}
class fourLeggedAnimal {
private $sound;
public function fourLeggedAnimal($sound){
$this->sound = $sound;
}
public function eat(){
echo $this->sound->makeSound();
}
}
$cat = new fourLeggedAnimal(new meow());
$dog = new fourLeggedAnimal(new bark());
I know this far from a perfect example. But it illustrates the technique and you can use this in many ways. For instance you can combine this with different creational patterns to build cats and dogs, it may not be so wise to have to know if a cat barks or meows.. But anyway.. it differs from having to make a base class and then extending it with a cat and a dog, and therefore have to make the "sound" method protected or overriding the public eat method.
/Peter
Upvotes: 1
Reputation: 468
I generally use private in some very specific occasion where the method/variable is very internal and shouldn't be read or write by any other subclass (so basically almost never). The only case in mind where I use private variable is for exemple :
final public function init():void
{
if(!_initialized)
{
_init();
_initialized = true;
}
}
protected function _init():void
{
// specific code.
}
In most of the other case the methods and variable should be useful for inheritance at least as a reading function. Because most of the time when I use code made by someone else, and when this code use private things it always and with a lot of trouble :
the wanted behavior is not already implement or complete
I can't use a method because it's private
I can't change this method because it's private
if it's protected (or if I change it as protected) then I can't rework the code (aka adding behaviors in between tow others instruction, because part of this code use private methods or variables...
= at the ends you almost change all the accessor to protected to get the ability of extending the class!
Thus, if you think this class could be extends prefer protected for everything except very specific case (if you think a specific method should only be used but not changed use final protected).
If you think this class shouldn't be extended in any case : use private.
Upvotes: 1
Reputation: 117417
I generally avoid private
. My reasoning goes that if you have an inheritance relation between two classes, and there are private members, then it is a very strong indicative that you should factor the private parts out into a separate object.
Upvotes: 4
Reputation: 13723
Well, the private keyword was intended with a purpose. If you don't want the variables to clutter up your inherited classes (or you don't want people playing with them in inherited classes) then why do you even consider making them protected?
Don't let people touch your private parts :)
Upvotes: 3
Reputation: 591
Personally, I find it proper to make as much private as you possibly can. I just look at each method and ask myself if I want a derived class to be able to call it. Making everything protected leaves open the door to having methods called incorrectly.
I guess it comes down to the questions "Is everything forbidden unless specifically permitted" or "Is everything permitted unless specifically forbiddden.
One additional factor is that it's easy to make a private method protected in a future release. It's almost impossible to privatize a method once it's made protected, as you never know what other code you invalidate.
Upvotes: 6
Reputation: 16311
If you intend to build a class for inheritance, you must design it that way, i.e. make those methods protected that allow other developers to change the behavior of the class along the lines that you intended. Simply making all methods protected is not a very good design. Bear in mind that all protected methods become part of the public API, so if you change things later, you will break other people's code.
In general, if you're not designing for inheritance, you should prohibit it.
Upvotes: 5
Reputation: 529
My instinct is to keep them private, until you need them to be otherwise.
It has been argued (sadly I've misplaced the link) that making methods private is antisocial, in much the same way as making them 'final', in that it's fairly dictatorial about how people may use your code.
I'm not convinced, however, and agree that you should expose only what you really need to. The exception would be a library or toolkit, where you'll expect users to want to extend (in the general sense) your code in ways which you would never foresee. In which case making well-chosen methods protected can be seen as providing flex-points.
Upvotes: 27
Reputation: 18220
If the function you've implemented is class-specific and shouldn't be used outside of the context of that class, then don't allow it to be inherited. For example, if we had an animal hierarchy, and one of the animals had something incredibly unique to them only, say "layEggsInSand()" like a turtle. This may be wholly unique to the turtle (tortoise, whatever!) therefore shouldn't be inherited by any other animal. In this context we'd say it's private. On the other hand if the function is "walk()" then it's not unique, therefore it should be inheritable.
It seems quite fuzzy at first because most of the time things should be inherited, but there are rarer cases when they shouldn't be inherited as they're unique to that type.
Upvotes: 1
Reputation: 3694
I would declare the methods as private. It clearly indicates that they are not part of the public API.
Don't worry about what may happen in the future.
Upvotes: 1
Reputation: 884
I think you should only expose what you need to when you need to. This makes doing impact assessments of changes easier. i.e. If a method is private, you know the impact will be minimal if you change it.
Upvotes: 12