3

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.

Community
  • 1
  • 1
anonuser0428
  • 11,789
  • 22
  • 63
  • 86

9 Answers9

8

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.

Edit:

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.

Community
  • 1
  • 1
jpmc26
  • 28,463
  • 14
  • 94
  • 146
3

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.)

Zim-Zam O'Pootertoot
  • 17,888
  • 4
  • 41
  • 69
1

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

Amongst other reasons, they allow for control of access to class fields/properties, and they allow for binding of properties that will allow listeners to be notified of any changes to them.

I have understood that I am completely wrong and they don't help with security at all.

This seems to me to be an overly broad and vague statement. They allow control of access to a property, and so that in and of itself increases "security". If you disagree, then to further help you with this, consider telling us your functional definition of security.

And when we say private or protected who exactly is this protecting the data-field or class or method from?

This information is readily available from any basic Java tutorial or book.

Isn't it still possible for people to get access to the method already know its there? Through reflection and other methods?

Yes, it is possible to access all methods, but doing so without extreme care can result in extremely fragile code.

but its always bothered me that I don't quite know the exact reasoning for one of the main OOP concepts of Encapsulation.

You will want to keep studying (as we all must do) including both beginning and advanced texts on the subject.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 2
    You seem to be saying that reflection only allows access to public fields and methods. [That's not the case.](http://stackoverflow.com/questions/1196192/how-do-i-read-a-private-field-in-java) – user2357112 Aug 11 '13 at 03:33
1

There's a constant tension in programming between "what do you want to have happen"—an abstract design—and "how do you get that to happen", a concrete expression of rules that achieve some result. If we had a Computer Oracle (not to be confused with Oracle-the-company), we might ask "What is the meaning of life?" and get the answer (42, of course). But we don't: we have to tell a computer to do stuff in fiddly little steps.

As soon as you break a problem down into an executable algorithm, with component pieces, you start to come up against issues with how the pieces interact. Programmers get things wrong, and cause pieces to interact incorrectly. Requirements change: a program made up of lots of pieces that do A, now has to do B instead (or in addition). For cost and time reasons, we want to re-purpose old code to do new things. All of these lead to bugs. If only we could have comprehensible, well-behaved big steps that we just compose out of comprehensible, well-behaved little steps....

Many early languages were "verb oriented": create a simple machine-level variable (like INTEGER or REAL), modify it, ADD X AND Y GIVING Z, and so on. If you needed to build a large amount of state to describe something, such as a Mars Lander, you had a large number of variables holding all the parts. It then becomes far too easy to apply the wrong verb to the wrong part, like attempting to read the temperature of the parachute, or rotate the orbital thrusters with a function that only works on the wheels.

"Typed" languages offer one approach to curbing bad interactions. If the rotate function/procedure only operates on a wheel type, you can't accidentally call it on the RCS system. But then you end up with a profusion of action verbs, thruster_rotate and wheel_rotate (although some typed languages offer namespaces so that you can do thruster.rotate(thruster_id) or similar, which won't interfere with wheel.rotate(wheel_number)).

Object Oriented Programming offers a different approach: the program's state can be kept in terms of individual "object states", and accessors operate on those objects. Now thruster.rotate() can work on an RCS thrusters while wheel.rotate() works on a wheel. It is, or at least can be, clearer what's working on what. (Note that OOPLs can and usually do have fancy namespaces too.)

Alas, people still make mistakes. Accessors give you (as a programmer) a way to allow other parts of the system—often written by other people—to interact with "your object(s)" in a well-controlled way, and maybe one more useful to them. If you have a temperature sensor, you can offer readings in both degrees_F and degrees_C even though internally, the actual reading is in microvolts. Protection (however loosely enforced—it's been noted that C++ must be from the Free Love era, in that it gives friends access to your private parts) at least allows you to state, in code form, your intentions as to who should fiddle with what.

In the end, programming is often much about abstraction: exposing that which needs to be exposed, but at the same time, hiding anything that should not be exposed. Accessors and protection give you direct control over what is exposed, and what is hidden. Even if they are mostly advisory (as in Python), they are still a direct statement: "If you're not working on this module, you're not supposed to use or modify this thing. It's just an implementation detail, not part of the interface."

torek
  • 448,244
  • 59
  • 642
  • 775
0

To my understanding, one of the key reasons behind using access specifiers (access modifiers) like public, private, static, protected is minimizing the probability of making accidental mistakes in your programming.

The existence of these in the objected oriented programming is due to the concept of encapsulation. When you develop large scale software, access specifiers come in very handy, be it security or minimizing risk of giving unnecessary access to your data/class/methods when it isn't really required.

Ali Gajani
  • 14,762
  • 12
  • 59
  • 100
0

There are many reasons for access specifiers, but it generally comes down to ease of creating and maintaining code. Other good answers are here too, I'll just put down some extra thoughts.

Consider that a lot of development, especially in Java, uses some sort of IDE. A good IDE is smart enough to only show you variables or methods in the little popup lists that you can actually see. So if I'm just using a class, not editing it, whenever I write an object of that class, only a filtered list of methods shows up, cutting out all the internal variables and methods; this makes coding much easier.

Another cool thing access specifiers allow you to do is mess around with getters and setters; basically, if a member is private, you can only access it via a getter or setter; but that means you could potentially put clever additional code into these methods. Maybe a setter will also call an event that warns others that the value has been set; or maybe a getter is more complex than just getting the value of a variable, maybe it does some calculations. If you didn't have to use that setter and could just access the variable directly, some developer might miss the fact they're supposed to use the setter for the above reasons, which would obviously create issues.

Marconius
  • 683
  • 1
  • 5
  • 13
0

I have been asking myself the question for a while too. My main concern is how to make certain methods accessible to the object's "owner" (the object of the same or a different class that created it), and not to "spectators" (objects that are provided a reference by the "owner" but only to call certain methods). This can be generalized to more than 2 privilege categories, of course.

I'd say the mechanisms provided by most (if not all) programming languages are very far from achieving objectives like this. They are much more precarious and in many cases not enforceable (or effectively enforced) at runtime. However, as comments/documentation, they are extremely valuable. Any developer willing to respect the intended encapsulation of a class will listen to these indications, in many cases with the help of the IDE.

The objective of encapsulation is not protecting the developer (and objects) of the class, but the developers (and objects?) using that class. A "private" modifier is similar to a label saying "Hazardous voltage. This unit is to be serviced by highly trained personnel only." If you go ahead and find a way of modifying the variable, the class will most probably crash. But with it, it is your application what is crashing. If you go to the original autor to complain, what do you think is going to be answer? What would be if you complain to the manufacturer of the machine with such label? OK. You did not change anything, but you just did have a "peek" and make your code read and depend on the value of that field. What if in a future version the developer of the original class decides to change the meaning of the field? Perhaps its measurement unit? Or completely remove it? Your program will crash, of course. But again, what would he/she reply if you try to complain? Most probably exactly what mom did so many times: "I told you!".

I did create a "security" mechanism for objects sitting on top of Java. Decided that without the collaboration of the programming langauge, it was not worth the effort. This was before AOP and annotations, though. Perhaps I should give it a new try.

I think I explained above the meaning of private. The opposite access modifier is of course public, and it doesn't deserve much more explanaition. protected and "package default" (absense of access modifier) correspond to a label "Hazardous voltage. This unit is to be serviced by moderately trained personnel only." Who is "moderately trained personnel"? Developers that will be aware if the class changes and would adapt their own code if necessary. People who are performing work that necessarily requires knowledge of the internalities class. This is, developers of classes in the same package as the class in question ("package default"), and developers of subclasses of the class in question or of classes in the same package (protected).

For more specific details, see Oracle's Java "Object Orientation" tutorial

Mario Rossi
  • 7,651
  • 27
  • 37
0

I'll leave the merits of encapsulation to the other answers (different programming languages have different philosophies on this, as do programmers).

however, i will address the security implications. as with many answers here on SO, just cause it got a lot of upvotes, doesn't make it correct (the question linked in the OP). While there are many ways to get around the access "restrictions" in a normal jvm, that doesn't mean the access modifiers don't have real security implications. if you have ever run an "untrusted" applet, then you have depended on the security of the access modifiers of the java language. that is because applets run in a jvm with a SecurityManager. when a SecurityManager is configured, then running code cannot get around the access modifier restrictions, and these restrictions have very real security implications. for instance, if untrusted could could modify the contents of a String instance, then it would be fairly trivial to circumvent the jvm SecurityManager and break out of the secure sandbox (and delete your hard drive).

jtahlborn
  • 52,909
  • 5
  • 76
  • 118
  • I think "cannot" is too strong a word. I believe they've been fixed, but old versions of Java have known security holes. See https://www.us-cert.gov/ncas/alerts/TA13-010A for an example. I don't think depending on them for security is wise, so it's better not to even think about access modifiers on those terms. That said, this thinking doesn't seem to apply to code I am writing; it applies to protecting Java API code that might put my computer at risk from untrusted code I am *running*. Given the existing vulnerabilities, I would prefer just to run that kind of code in a VM for greater safety. – jpmc26 Sep 01 '13 at 03:51
  • @jpmc26 - yes, it applies to code you are running. that doesn't mean that this answer should be downvoted. nothing i wrote is incorrect, even if it doesn't apply to your particular situation. – jtahlborn Sep 02 '13 at 13:57
0

Access specifiers are just like locker keys. You must have keys to open your main gate or room doors of top management, other wise any one can open these doors. It is information security at lowest level. The information your heads has is stored in the heads of CEO, CFO etc. of an organization dont worry about that.

Rashid
  • 11
  • 4