I have a general question regarding the reason for object oriented access specifiers. I have never completely understood the reasoning why they exist and just thought they were there as a very rudimentary form of code-security but after looking at the discussion on this thread
Does Python have “private” variables in classes?
I have understood that I am completely wrong and they don't help with security at all. So are access specifiers just considered good programming practice in object oriented design? And when we say private or protected who exactly is this protecting the data-field or class or method from? Isn't it still possible for people to get access to the method already know its there? Through reflection and other methods?
I apologize if this question seems basic or a bit meta-oop but its always bothered me that I don't quite know the exact reasoning for one of the main OOP concepts of Encapsulation.
Access modifiers are used to indicate how you intend for callers to use your code. They are especially important when you maintain internal state. Consider a class that keeps a count:
public class Thing {
public int count = 0;
public void doSomething() { count++; }
public int getHowManyTimesDone() { return count; }
}
What's the problem with this code? If a caller modifies count, my code violates its contract:
Thing x = new Thing();
x.doSomething();
x.doSomething();
x.count = 0;
System.out.println(x.getHowManyTimesDone());
My class' contract says that this should print 2, but it prints 0 because the caller modified count. By making count a private variable, I am telling callers, "Hey, you're not supposed to touch this! Doing so might make this code break!"
Python doesn't have a concept of privacy. Rather, by convention, a single underscore prefixed to a variable provides the same warning to callers: "If you touch this, it could break this code!" This is probably most akin to protected. A double underscore also triggers name mangling, which suggests that not even subclasses should use it; this would be most akin to private. In Python, it's the caller's responsibility to accept the risk if they access these members anyway, but programmers are encouraged to make as much as possible public.
As for who is implementing the visibility of variables in Java, it's the runtime itself. There are indeed clever ways around this, though. I believe reflection provides some means, and anyone getting into the bytecode or JVM itself can certainly do something. Consider the kinds of things mocks do; they can convince the JVM that the mock is a particular type even though it's not.
One more thing. In Java, programmers are encouraged to keep all instance variables private and use methods to access and mutate them. This is for maintainability, not for a philosophical reason about hiding details. Because Java does not have a C# or Python-like property mechanism, if you need to add logic to the getting or setting of an instance variable, all code depending on that instance variable will need to be modified to use the methods. By always using methods to access variables, you minimize the dependent code you would break by making such a change. In other words, it's a kludge for dealing with a shortcoming in the language.
They're there to make it easier to reason about the program. For example, if you've got a private field with a public setter that ensures that some property of the field is maintained, then you only need to ensure that the code within the field's class doesn't violate the property; if the field were public then you'd need to ensure that all of the classes don't violate the property. (Another class can use reflection to violate the property, but in that case you catch it in code review and fire the programmer who's responsible.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With