240

Why do we need private variables in classes?

Every book on programming I've read says this is a private variable, this is how you define it but stops there.

The wording of these explanations always seemed to me like we really have a crisis of trust in our profession. The explanations always sounded like other programmers are out to mess up our code. Yet, there are many programming languages that do not have private variables.

  1. What do private variables help prevent?

  2. How do you decide if a particular property should be private or not? If by default every field SHOULD be private then why are there public data members in a class?

  3. Under what circumstances should a variable be made public?

10
  • 12
    Your question sounds very language-agnostic, but you have tagged it as java and c++. If you are interested in perspectives from outside those two languages, you should probably say so.
    – James
    Apr 10, 2012 at 12:08
  • 10
    For the record, creating a private method doesn't increase "security". Other parts of your application can still access private members using reflection.
    – kba
    Apr 10, 2012 at 14:07
  • 3
    The usage and difference of private and public variables, and why we have them, can only be understood in the context of general Object-oriented principles. It cannot be understood separately. You probably need to look at it from that perspective, things may get clearer. Apr 10, 2012 at 16:37
  • 1
    possible duplicate of When are Getters and Setters Justified Jun 27, 2013 at 11:30
  • 4
    If you catch anyone using a seatbelt in their car, you should take their driving license away, since obviously they don't trust their own abilities to drive.
    – gnasher729
    Jun 17, 2016 at 9:02

15 Answers 15

335

It's not so much a matter of trust, but rather one of managing complexity.

A public member can be accessed from outside the class, which for practical considerations means "potentially anywhere". If something goes wrong with a public field, the culprit can be anywhere, and so in order to track down the bug, you may have to look at quite a lot of code.

A private member, by contrast, can only be accessed from inside the same class, so if something goes wrong with that, there is usually only one source file to look at. If you have a million lines of code in your project, but your classes are kept small, this can reduce your bug tracking effort by a factor of 1000.

Another advantage is related to the concept of 'coupling'. A public member m of a class A that is used by another class B introduces a dependency: if you change m in A, you also have to check usages of m in B. Worse yet, nothing in class A tells you where m is being used, so again you have to search through the entire codebase; if it's a library you're writing, you even have to make sure code outside your project doesn't break because of your change. In practice, libraries tend to stick with their original method signatures as long as possible, no matter how painful, and then introduce a block of breaking changes with a major version update. With private members, by contrast, you can exclude dependencies right away - they can't be accessed from outside, so all dependencies are contained inside the class.

In this context, "other programmers" include your future and past selves. Chances are you know now that you shouldn't do this thing X with your variable Y, but you're bound to have forgotten three months down the road when a customer urgently needs you to implement some feature, and you wonder why doing X breaks Y in obscure ways.

So, as to when you should make things private: I'd say make everything private by default, and then expose only those parts that absolutely have to be public. The more you can make private, the better.

14
  • 27
    +1 for getting at the heart of the issue, though I've personally found my code easier to maintain when I stopped going through hoops just to ensure that a frequently used variable stays private. Sure an error may come up in the future, but it's 60 less lines of code to sift through, and less variables and functions to boot ;) Apr 10, 2012 at 5:57
  • 57
    The holy grail of modern computing is keeping complexity down.
    – user1249
    Apr 10, 2012 at 9:58
  • 1
    I always like to say that part of debugging is not just driving directly towards "what went wrong," but taking the roundabout process of figuring out "what didn't go wrong," and focusing my investigation on what is left. If I can get the compiler to assist me with tools like private variables to define "what cannot possibly have occurred," that saves me a load of time. Only in the rare cases where I prove that what did go wrong cannot have occurred do I have to dig into the more frightening assumptions, like perhaps a buffer overrun overwriting my private data.
    – Cort Ammon
    Sep 22, 2015 at 23:37
  • 3
    Exactly that. When people hear "information hiding", they think that they should use private variables for things like encryption keys, database credentials, etc. Jun 17, 2016 at 14:31
  • 2
    @AdamZerner see "Tell, don't ask" (martinfowler.com/bliki/TellDontAsk.html) about having getters/setters in the first place - but otherwise yes, because you should be free to change the internal representation of the value anytime you wish. As always, there are exceptions... (e.g. DTOs)
    – doubleYou
    Jan 18, 2018 at 18:17
115

Private variables help prevent people from depending on certain parts of your code. For example, say you want to implement some data structure. You want users of your data structure to not care how you implemented it, but rather just use the implementation through your well defined interface. The reason is that if no one is depending on your implementation, you can change it whenever you want. For example, you can change the back-end implementation to improve performance. Any other developers who depended on your implementations will break, while the interface users will be fine. Having the flexibility to change implementations without effecting the class users is a huge benefit that using private variables (and more broadly, encapsulation) gives you.

Also, it's not really a "trust crisis". If you make a piece of data public, you cannot ensure that no one is depending on it. It's often very convenient to depend on some implementation-specific variable, instead of going through the public interface, especially in the heat of a deadline. Further, developers won't always realize that they are depending on something that might change.

So this sort of answers your other questions, I hope. All your implementation details should be private, and the public part should be a small, concise, well-defined interface for using your class.

5
  • 25
    IMO it's also about communication between the lib author and the lib consumer. Public interface is like "use this" and privates are like "don't use that" except that in Java, you really cannot use it by accident if make it private so it's safer and clearer that way.
    – chakrit
    Apr 10, 2012 at 5:55
  • 5
    @chakrit and others: Note that those who are really out to use your private fields and methods can do so (via reflection). private is less than "not primarily intended for security", it provides no "security" to speak of. It's just a strong hint (delivered through the compiler) not to access it.
    – user7043
    Apr 10, 2012 at 10:35
  • @delnan note the phrase "by accident" yeah maybe I should be more clear on that.
    – chakrit
    Apr 10, 2012 at 10:39
  • @chakrit Yes, I didn't mean to imply you were wrong. I just wanted to promote that point.
    – user7043
    Apr 10, 2012 at 10:41
  • 1
    @delnan: Private fields do, in some languages, provide certain forms of security. For example, see Eric Lippert's answer to Do the access levels and modifiers (private, sealed, etc) serve a security purpose in C#?.
    – Brian
    Jun 27, 2013 at 14:31
31

The keyword here is Encapsulation. In OOP you want to use private variables in order to enforce proper encapsulation of your objects/classes.

While other programmers are not out to get you, they do interact with your code. If you do not make a variable private, they may well refer to it in their own code without wanting to do any harm at all. However, if you need to get back to your class and change something, you no longer know who uses which variable and where. The goal of encapsulation is to make the external interface of the class explicit so that you know only these (typically) methods could have been used by others.

  1. Hence, private variables ensure that the corresponding variable remains in the defining class only. If you need to change it, the change is local to the class itself.

  2. In traditional lanugages like C++ or Java, you usually make everything private and only accessible by corresponding getters and setters. No need to decide much really.

  3. Sometimes, f.ex. in a C++ struct, you need a class only as a way to group several things together. For example, consider a Vector class which has an x and a y attribute only. In those cases, you may allow direct access to these attributes by declaring them public. In particular, you must not care if some code outside modifies an object of your class by directly writing new values into x or y.

As an additional point, notice that this matter is regarded slightly different in other languages. For example, languages that are strongly rooted in functional programming emphasize data immutability, i.e. data values cannot be changed at all. In such cases, you do not have to care what other programmers (or rather their code) do to your data. They simply cannot do anything that could affect your code, because all data is immutable.

In those languages, you therefore get something called uniform access principle, where one deliberatly does not distinguish methods like getters and setters, but provides direct access to the variable/function. So you may say that private declarations are quite a lot more popular in the object-oriented scenarios.

This also shows how broadening your knowledge to include other fields makes you view existing concepts in a whole new way.

1
  • 1
    +1 "While other programmers are not out to get you, they do interact with your code." Programmers using your code are not inherently evil. By using private variables you make sure that they (and you, in the future) don't get hurt using the code. It also helps you to design a better API and document it.
    – rszalski
    Oct 5, 2013 at 7:00
8

Private variables ensure that later references outside the scope of an object or function won't inadvertently affect other variables. For large programming projects, this can help avoid a lot of interesting problems (that are usually not caught by compiler).

For example, prototypical languages like Javascript can allow users to plaster on variables as they see fit:

function SomeObject() {
    this.a = 2; //Public (well, actually protected) variable

    this.showA = function() {
        alert(this.a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 3. Uh oh!

If that variable was private, it wouldn't be able to be changed from the outside:

function SomeObject() {
    var a = 2; //Private variable

    this.showA = function() {
        alert(a);
    }
}

//Some lines down...

var obj = new SomeObject();
obj.a = 3;
obj.showA(); //Will alert 2

That said, not all variables need to be private and excessive use of private variables can actually make code more cumbersome. Trivial fields that don't seriously impact an object don't need get() and set() methods.

Private variables also make it easier to expand code in the future, without relying on heavy documentation as to what the many public variables do. There's less of a threat of accidentally breaking functionality if less variables can be overwritten.

Public variables should be used when an object/function will be accessing other objects/functions, since as a rule, private variables can't do this. You may have anywhere from a few to quite a few public variables, and it's not a bad thing to use them if they're used correctly.

2
  • It's not obvious why alerting 3 would be an "uh oh!" in this case. Maybe that's what the programmer wanted to happen.
    – user253751
    May 9, 2019 at 2:18
  • @immibis Perhaps, and maybe I should have elaborated more in the answer. But access to properties can open the door for violating some OOP principles such as open-closed principle or LoD, as you're potentially exposing implementation details. 'course to your point it depends on what the property is exactly. Most languages use objects as references, and when references of objects get passed around and fellow devs quietly change properties, it can be REALLY hard to debug. IMO it's much easier and more extendable to work with methods if you have a class instance. May 9, 2019 at 20:45
6

There are some good answers citing the benefits to future maintainers and users of a class. However, there are also benefits to the original design. It provides a clear demarcation point between when your goal is to make things easier on yourself, and when your goal is to make things easier on the class user. When you choose between public and private, it signals to your brain to switch to one mode or the other, and you end up with a better API.

It's not that languages without privacy make such design impossible, just less likely. Instead of being prompted to write something like foo.getBar(), people are inclined to think a getter isn't necessary, because it's easier to write foo.bar, but then that decision isn't revisited when you later end up with longer monstrosities like obj.container[baz].foo.bar. Programmers who have never worked in a stricter language may not even see what's wrong with that.

That's why in languages without privacy people will often adopt naming standards that simulate it, such as prepending an underscore to all "private" members. It's a useful signal even when the language doesn't enforce it.

3

All variables should be private unless they absolutely need to be public (which is almost never, you should use properties/getters and setters).

Variables largely provide the state of the object, and private variables prevent others from going in and changing the state of the object.

4
  • 6
    A way too narrow view of the subject matter. There are cases where public field access is warranted, even preferred Apr 11, 2012 at 19:59
  • One certainly can design objects whose state cannot be changed (immutable objects), but this is not a general rule applied to all classes. In my experience, most objects make it very easy for others to change the state of the object.
    – David K
    Jul 12, 2014 at 23:41
  • 1
    @DavidK Maybe what bbb meant to say is that "private variables prevent others from going in and indiscriminately changing the state of the object." Public methods may change the private state of the object, but only in ways that are necessary and consistent for the functioning of the object.
    – Max Nanasy
    Jul 17, 2014 at 20:57
  • @Max Nanasy: Yes, one can control how the state is changed when one offers only methods in the public interface. For example, there might be a relationship among the members that must be satisfied in order for the object to be "self-consistent", and you could allow a self-consistent state to be changed only to another self-consistent state. If all those variables are public then you cannot enforce this. But there can also be objects where you do not want to allow any change, so it is important to make clear which of these things we're talking about.
    – David K
    Jul 17, 2014 at 21:30
2

See this post of mine to a related question on SO.

The short of it is that variable scope allows you to show consumers of your code what they should and shouldn't be messing with. A private variable may hold data that has been "vetted" by using a property setter or a processing method to ensure the entire object is in consistent state. Changing the private variable's value directly may cause the object to become inconsistent. By making it private, someone has to work really hard, and have really high runtime permissions, in order to change it.

Proper member scoping is thus key in self-documenting code.

2

I'm going to talk about the value of encapsulation from a different perspective using a real example. Quite some time ago (early 80s) a game was written for the Radio Shack Color Computer called Dungeons of Daggorath. Some years ago, Richard Hunerlach ported it from a paper assembler listing to C/C++ (http://mspencer.net/daggorath/dodpcp.html). Some time later, I got the code and began to re-factor it to give better encapsulation, (http://dbp-consulting.com/stuff/).

The code was already factored into different objects to handle scheduling, video, user input, dungeon creation, monsters, etc. but you could definitely tell that it was ported from assembler. My biggest task was to increase encapsulation. By that I mean to get different parts of the code to get their noses out of each other's business. There were many places for example, that would change video variables directly to have some effect. Some did it with error checking, some not, some had subtly different ideas of what changing that thing meant. There was much duplication of code. Instead, the video section needed to have an interface to accomplish the desired tasks, and the code to do it could be all in one place, one idea, one place to debug. That sort of thing was rampant. Every object directly accessed every other object and code was duplicated everywhere.

As the code began to get teased apart, bugs that hadn't even been diagnosed went away. The code became higher quality. Each task became the responsibility of one place in the code and there was only one place to get it right. (I still find more every time I make another pass through the code.)

Everything that is visible about your code is your interface. Whether you mean it to be or not. If you limit visibility as much as possible then you won't be tempted to put code in the wrong place later. It makes it obvious what part of the code is responsible for which data. It makes for better, cleaner, simpler, more elegant design.

If you make an object responsible for its own data, and provide interfaces to everyone else that needs something to happen, your code gets a LOT simpler. It just falls out. You have small simple routines that do only one thing. Less complexity==less bugs.

3
  • The hard balance between "the freedom of our lib users" and "less trouble to us". I am starting to believe that encapsulation is better in a sense that I will prevent bugs on my own coding, and I will help end users to prevent bugs too. But the lack of freedom may simply put them away also, looking for alternatives... May be coding not yet used but foreseen functionalities thru public methods can help on balancing that, but demands more time. Jun 17, 2016 at 2:11
  • Too bad the refactored version isn't on github....
    – jmoreno
    Jan 19, 2018 at 11:42
  • Example that can be used against encapsulation. Encapsulation indeed is not needed to create a quality game.
    – Basilevs
    14 hours ago
2

It has nothing to do with trust or fear of attacks, it is solely about Encapsulation -- not forcing unnecessary information on the user of the class.

Consider private constants -- they should not contain secret values (those should be stored elsewhere), they can't be changed, they don't need to be passed into your class (otherwise they would have to be public). The only possible use for them is as constants in OTHER classes. But if you do that, those classes now depend upon your class, to do work that is unrelated to your class. If you change the constant, other classes might break. That's bad from both sides -- as the writer of your class, you want the freedom to change as much as possible, and don't want to worry about things outside your control. A consumer of your class wants to be able to depend upon the exposed details of your class, without worrying about you changing it and breaking their code.

A consumer of your class wants to know everything needed to INTERACT with your class, and does not want to know anything about your class that doesn't change how they do so: it is useless trivia. If you have used a langauge with reflection, how often have you used it to learn not how some class does something or where it is throwing an exception unexpectedly, but simply the name of the private fields and methods? I'm betting never. Because you have no use for that knowledge.

1

The OOP concept has inheritance has one of its features (Java or C++). So if we going to inherit (meaning we are going to access the variables of the inherited class), there's the possibility of affecting those variables. So we have to decide whether the variables can be changed or not.

For this purpose only, we are using access modifiers in OOP. One of the modifiers is private which means it can be accessed only by that class. Any other class can't affect those variables.

As we know, protected means it can be accessed by the class that is going to inherit.

Why there's a modifier concept in OOP, is due to these reasons (any class can access other class variables using the OOP concept). If there's no modifier concept, it means it would have been difficult while inheriting classes or using other OOP concepts.

1
  • What do private variables help prevent?

It's about making it clear what properties and methods are interface and which ones are actually core functionality. Public methods/properties are about other code often other developer's code using your objects. I've never worked on teams of 100+ on the same project, but in my experience of maybe teams of 3-5 with up to 20 other developers using stuff that I've written, the other concerns seem silly.

Note: I'm primarily a JavaScript developer. I don't generally worry about other developers viewing my code, and I operate in full awareness that they could simply redefine my stuff at any time. I assume they're competent enough to know what they're doing first. If not, it's unlikely I'd be working on a team that doesn't use source control.

  • How do you decide if a particular set of properties should be private or not? If by default every field SHOULD be private then why are there public data members in a class?

I used to think it was silly to put getters and setters on private properties when you weren't really performing any kind of validation or other special treatment of the property to be set. I still don't think it's always necessary, but when you're dealing with large scale, high complexity, but most importantly a lot of other devs relying on your objects behaving in a consistent manner, it can be useful to do things in a consistent and uniform way. When people see methods called getThat and setThat, they know exactly what the intentions are, and they can write their objects to interact with yours with the expectation that they'll always get tomatoes rather than tomahtos. If they don't, they know your object is giving them something it probably shouldn't, which means it's allowing some other object to do something with that data it probably shouldn't. You can control that as the need arises.

The other big advantage is that it's easier to have your objects hand off or interpret values differently from a getter or setter based on some kind of varying state context. Because they're accessing your stuff with a method, it's much easier to change how your object operates later on without breaking other code that depends on it. The important principle being that only your object actually changes the data you've made it responsible for. This particularly important to keeping your code loosely coupled which is a huge win in terms of portability and ease of modification.

  • Under what circumstances should a variable be made public?

With first-class functions (you can pass functions as arguments), I can't think of a lot of great reasons other than it not being hugely necessary to do so on smaller scale projects. Without it, I suppose you might have members that are getting processed heavily and regularly by other objects to the degree that it seems a bit crufty to constantly call get and sets on an object that doesn't really touch that data itself, but that in itself would make me wonder why the object was responsible for that data. Generally speaking, I would tend to want to re-examine my architecture for flaws before deciding a public data property is necessary. IMO, there's nothing wrong with a language letting you do something that is usually a bad idea. Some languages disagree.

1
  • IMHO, there's nothing particularly wrong with having a public class whose sole purpose is to expose public variables. Indeed, the JVM has a number of built-in classes for that purpose: int[], double[], Object[], etc. One should, however, be very careful about how one exposes instances of such a class. The meaning of void CopyLocationTo(Point p); [accepting a Point from the caller] is clearer than Point location(), since it's unclear what effect Point pt = foo.location(); pt.x ++; will have on the location of foo.
    – supercat
    Dec 23, 2013 at 20:39
1

imo @tdammers is not right and is actually misleading.

Private variables exist to hide implementation details. Your class A might be using an array to store scores. Tomorrow you may want to use a tree or priority queue instead. All the users of your class need is a way to input scores and names addScore() and a way to figure out who are the top 10 getTop(n).

They don't need to access the underlying data structure. Sounds great? Well, there are some caveats.

You shouldn't store a lot of state anyway, most of it isn't needed. Storing state will complicate your code even when it's "segregated" to a specific class. Think about it, that private variable probably changed because another object called a method of that class. You still need to figure out when and where that method was called and that public method can be called anywhere theoretically.

The best thing you could do is limit the amount of state that your program contains and use pure functions when possible.

0

As stated by others, private variables are good to avoid miss-usages leading the object into an inconsistent status and hard to track bugs and unforeseen exceptions.

But in the other hand, what has been mostly ignored by the others is about protected fields.

An extended sub-class will have full access to protected fields, making the object as fragile as if such fields were public, but that fragility is limited to the extending class it-self (unless it exposed such fields even more).

So, public fields are hard to be considered good, and to the date the only reason to use them is for classes used as configuration parameter (a very simple class with many fields and no logic, so that class is passed as a parameter alone to some method).

But in the other hand, private fields lowers the flexibility of your code to other users.

Flexibility vs Troubles, pros and cons:

Objects instantiated by your code in the vanilla class with protected fields are safe and are your sole responsibility.

In the other hand, objects extending your class with protected fields, instantiated by the users of your code, are their responsibility, not yours.

So, not well documented protected fields/methods, or if the users do not really understand how such fields and methods should be used, have a good chance of causing unnecessary trouble to themselves and to you.

In the other hand, making most things private will lower the users flexibility, and may even put them away looking for maintained alternatives, as they may not want to create and maintain a fork just to have things happen their way.

So, a good balance between private, protected and public is what really matters.

Now, to decide between private and protected is the real problem.

When to use protected?

Everytime you understand a field can be highly flexible, it should be coded as protected. That flexibility is: from becoming null (where null is always checked and recognized as a valid state not throwing exceptions), to having constraints before being used by your class ex. >= 0, < 100 etc, and automatically fixed for over/under-flowed values, throwing at most a warning message.

So, for such protected field you could create a getter and only use it (instead of direcly using the field variable), while other users may not use it, in case they want more flexibility to their specific code, in my example could be like: if they want negative values to work fine at their extended class.

-1
  • Accessing a variable mean accessing its value when the program runs, making a variable private protects its value when the code runs.
  • The point of so-called "data hiding" is to keep internal data hidden from other classes which use the class. Those other classes should only access behavior by calling methods on the class, not by changing values of variables directly.
  • By making the variable a private data member, you can more easily ensure that the value is never modify or change. On the other hand, if the variable is public, another class could modify or change the value which can cause other parts of the code to crash.
1
  • 1
    this doesn't seem to offer anything substantial over points made and explained in prior 17 answers
    – gnat
    May 8, 2019 at 5:16
-3

You should first understand the concept of object oriented programming. It has abstraction, encapsulation etc.

Abstraction - You get the idea of the logic without need to know underline details of the implementation.

Encapsulation - You can not see the underline implementation of the object. Only you can see the public interface of the object.

Now in specific implementation with one of object oriented program like C#, Java, C++ you can implement these concepts.

private - The implementation which should be hidden from the outside world. So that you can change that and the user of your class are not affected.

public - This is the interface by which one can use your object.

1
  • 1
    protected - directly accessible by sub-classes (extenders) (java). Jun 17, 2016 at 2:13

Not the answer you're looking for? Browse other questions tagged or ask your own question.