To take your analogy of a library with books, should anyone who goes there be able to tear pages out of any books there and just take the pages? Should they be able to take books if they don’t have a library card (which incidentally requires permission to acquire)? What if the way they want to read a book is to remove its binding and spine and array all the pages on the floor in front of them; is that an acceptable use of the library? Even in real life, there are certain boundaries that allow things to work the way they are supposed to.
Going back to software development, these kinds of boundaries can help with understanding what code is supposed to do. If I write an implementation of a stack, which is basically an array that you can only add to, access, or delete from at the end, it shouldn’t matter whether it’s an array internally or some other thing. Someone who is using a stack should know why they’re doing that, and so they should never need to access anything except the end. If they’re using a stack and find that, for some reason, they need to access something in the middle, then they need to consider 1) if they really need to do that, and 2) whether they should be using a stack. The answer to one of those questions will be “no”.
There are some cases in which things which aren’t accessible to a developer should be. However, most of the time if you’re making a library it’s better to have everything private except what you know you want to be public. One reason is what Hinrik mentioned: it’s better if you can improve your library without breaking anyone else’s code. If real-life libraries allowed some of the things I mentioned above, people would do them. If it gets them what they want in the moment, most of the time people won’t worry about what the long-term consequences will be. Similarly, if I allow someone to use the array that my stack is based on, they will. It doesn’t matter how many warnings there are in the documentation or even that it’s called a “stack”. So when I decide later that there’s actually a clever way that I can use a hash or set or slice or whatever instead of an array, I will break their code. We obviously want to minimize broken code (though there are good reasons to do it anyway), so we should restrict their access in the first place.
However, even without considering broken code, creating a library involves making promises to the user. Part of that is behavior: if my user wants to put something on their stack, it should put it on the stack so they can get it later. However, they should also be able to rely on that thing being the same if it’s been in the middle of the stack for a while. It’s helpful to my user if they aren’t allowed to mess with the middle of the stack because then later, when they are getting things from the stack, everything is still where and how they expect.
I wanted to end this with another example of using
delegate that doesn’t fall under the stuff I (and others previously) have talked about. After all, you didn’t ask a question about why variable and method privacy exists. Unfortunately, though, I have to go. I’ll try to remember to add to this later with a good example of when you can use
delegate, even if you refuse to believe that the reasons we’ve given are good ones.