The private variables debate is going around the PHP world again. Brandon Savage posted a pair of articles pointing out the perils of private variables, boiling down mostly to them making extension infesible or impossible. Anthony Ferrara replied with his own article, arguing that the real problem is using inheritance in the first place rather than composition. I figured I'd weigh in on my own blog rather than in a comment. :-)
As an academic matter, I agree with Anthony. Composition and interfaces are more flexible than inheritance. I've been preaching the interface gospel within Drupal almost as long as I've been preaching Dependency Injection.
As a practical matter, however, rarely is the world so clear and academically pure. Sometimes, looking at a class I can see that it's API *and* implementation are 95% of what I want, but I need to tweak one piece. And that piece is an internal part of the implementation. It would be lovely if all classes were well-factored so that what I wanted to override in a wrapping adapter class was easy to do externally, but in practice that's simply not the case more often than not.
Even in a very well-designed system like Symfony2 I've repeatedly run into places where I had real, legitimate use cases for wanting to extend-and-tweak a class, but ran into something being private which made it require a lot of ugly contortions. And those contortions are contortions that I would not have been able to accomplish via pure composition at all.
Further, the PrinterInterface above is a nice and simple example. Nice and simple examples are great, but far too often the real world is not nice or simple. As a concrete example, take the SelectQueryInterface of Drupal 7/8's database library.
The interface has 26 public methods. Yes, 26. And I think if you examine the interface you'll see that it's entirely justified, and not a God Object (or God Interface). That problem space simply requires a lot of methods.
So to make a trivial wrapper around that object in order to do a little extra processing around just one method, you need *twenty five* stub methods that do nothing but forward the call. That's a huge burden to put on the developer, as now you're talking about, in well-formatted code, on the order of 100 lines of dumb boilerplate code just to "cleanly" write an adapter class even before you get to the meaningful part of the class. And, that does add runtime overhead for extra stack calls.
But it gets worse. Suppose that your wrapping objects have legitimate need to add methods. Their whole purpose is to take an object of one type (say, a select query building object) and add some additional functionality. That's what adapters do. Unfortunately, that means an adapter can't rely on the thing it's wrapping being only the interface it expects, as it may have other meaningful methods that need to be forwarded. PHP's only saving grace in this department is __call(), which is an ugly and slow hack but the only option here.
We ran into that exact problem in Drupal 7 with select query builders, and the only solution we had was a complex and fugly system of Extenders that I hate with a passion. Really, it's just a utility shell and, yes, base class for an object that has 100 lines of boilerplate call forwarding, plus a default __call() implementation. I hate it, but it's the only system we could come up with to work around the limitations of a "compose everything" mindset. (If someone has a better suggestion, I'd love to hear it.)
There was a proposal a while back for PHP to have some sort of "forward" keyword so that a class could declare "this interface I have? Forward all methods from it to this object I'm composing. kthx." That would neatly solve the 100 lines of boilerplate problem, but it didn't go anywhere unfortunately and Traits happened instead.
In an ideal world would private methods be fine, because you never need to extend classes? Sure. But rarely do I see code written in an ideal world. Composition and interfaces should be preferred over extension, absolutely, but it's not always possible or practical. In the real world, gaps happen and you need to extend things, and if the wrong thing is private, you can't.
That's why Drupal has a policy of not using private anything: We value extensibility and flexibility over purity, even while striving increasingly for architectural cleanliness in more recent efforts.