Because the purpose of access control levels is not this.
The idea of encapsulation is to ensure that your classes can not suffer harmful interference from other classes.
That is, if you designed class X to solve problem Y, you do not want your neighbor to design a class Z that uses its class X in a totally inadequate way and end up breaking with the premises that functioning properly. With this access control, it's much easier to develop robust, secure, well-testable, and more stupid-proof code thanks to the encapsulation.
The idea is to expose the other classes, which may have been designed by different people, only valid forms that make sense to interact with it. To get a fairly beaten concrete example, imagine the String
class. It has a private field of type char[]
(in OpenJDK 8), and so a String
can be used safely and that makes sense, you will not want the class Gambiarra123
than your nephew's nephew invented it to end up messing with the% s of the entire system for some stupid reason.
From this concept of exposing only what can be used and manipulated in a healthy way by other classes or not, comes the levels of public and private visibility, which are the most used. The protected and packet visibility levels of java (and String
of C ++) are intermediate cases for specific exceptional situations and in practice apply very rarely.
In this way, with public or private access control it is possible to separate which part of the class corresponds to the behavior that is exposed to the external world of the part that is just some internal detail so that its implementation can function properly and perform what is proposed.
Now comes the question: If you wrote the class X, then it does not make much sense for you to protect the class X code against misuse of itself, after all, it's the same code written by the same people . And it is because of this that programming languages in general have access control rules based on classes and not on instances. It does not make sense for a class's code to want to restrict access control to something even more restricted than just itself.
In short, access control is something that is used to organize and protect code before it is submitted to the compiler, not objects in memory during execution. Instance is a concept that only comes up in another stage when the code is already running, and at this stage access control is no longer needed because the build step has already passed.
In case this allows " one person to end up reading another person's mind", for this, the ideal would be to work with interfaces where a person sees other people and knows what they can do, but can not read your thoughts. Each person has their specific behaviors, which are often not known in depth by other people. Now when you work with class code, you already have all the details regarding the behavior and in this case if one person ends up reading the other's thinking improperly, it's because it's a programming error in the friend
, and not from harmful interference by another class.
Finally, there are some languages that end up implementing the restriction of access in term of instances. Scala has the Pessoa
modifier. Ruby interprets private[this]
that way.