Why declare variables private in a class?

30,044

Solution 1

It's not that it's more efficient, it's that it's more maintainable and a good practice.

For example, with setter methods, you could have your setTelephoneNumber actually check that the String is a valid telephone number before you actually do the setting. You couldn't possibly do that if you made the variable public. Using a setter from the very beginning means that you can go back and e.g. add validation later on, whereas if you had made the variable public, you would have to add a setter and modify all your users everywhere to use the setter instead of modifying the variable directly.

Solution 2

Pizza Delivery Analogy

  1. You order a Pizza for delivery.
  2. Pizza boy knocks the door and expects you to pay for it.
  3. You take out the money from your purse and hand it over to the delivery boy. (You are in control of hiding the internal details (drivers license etc.)) Alternatively,
    • You could hand over the purse to the delivery boy and ask him to take the money from it. By doing this you are no longer in control. You are exposing internal details.

Read about Information Hiding and Encapsulation is not information hiding.

Solution 3

People will give you a million regurgitated reasons why it is better, but it is only better in some cases, not in all of them unequivocally. For example, take Java's own class GridBagConstraintsit has no methods at all (if you don't count clone, which it has anyway; all Java classes inherit it from Object). Why? Because there's a case where this is in fact more practical. And GridBagConstraints is a Java Bean in the purest sense: it's all about properties, no business logic there.

Let me report on another fact from practice: no setter ever validates its input; no getter ever calculates its result. In the world of JavaBeans, any such behavior will soon get in the way of the universal assumption that setters set, and getters get. Basically, if you diverge in any way from the exact equivalent of public fields, you lose.

The modern Java APIs, like Hibernate, acknowledge this fact by accepting naked public fields on an equal footing with JavaBean-style properties. Earlier versions didn't allow that, but as experience with Java accrues, the realization is finally dawning that public fields are OK.

Solution 4

You have to operate on the assumption that, at some point, someone else will use your code - and that someone else could be you, a year down the line. If you see a public property on a class, you should be able to assume that it's free for you to manipulate, if it's not to be directly modified you shouldn't be able to see it externally.

A good literal example would be the dimensions of a bitmap object. Most machines wouldn't like it if you tried to draw a bitmap of dimensions -10x-10, because such a thing would obviously be impossible to represent on a screen. If the width/height properties of this bitmap were simply public variables, it's possible they might be set to invalid values later on by a well-meaning coder (NEVER assume that it wouldn't happen), and when it came to render it - bang, you've got a frozen computer.

By hiding the variables and using a setter, you can prevent this ever happening:

private int _width = 10;

public void setWidth(int value)
{
     //Prevent the value moving into invalid range:

     if(value < 1)
          value = 1;

     if(value > 4096)
          value = 4096;

     //Now apply it
     _width = value;
}

However, for speed and convenience you don't have to develop your code like this at first - just make sure you go through it afterward and hide what you need to!

Share:
30,044
Andrew Martin
Author by

Andrew Martin

New picture, as I'm no longer as grumpy :)

Updated on February 05, 2020

Comments

  • Andrew Martin
    Andrew Martin over 4 years

    Folks I'll start by apologising as I'm sure this has been answered elsewhere - I just can't find an answer that explains it in a way I understand! I'm doing an MSc conversion course and there are some elementary basics that I'm still struggling with this, including this one - why making a variable private is better.

    Say I have a Java class called Person, with a print method. I could create it and define it as such:

    public class Person
    {
        public String name;
        public String telephoneNumber;
    
        public void print()
        {
           System.out.println(name + " " + telephoneNumber);
        }
    }
    

    Then, in a main class, I could write the following code:

    class testPerson
    {
      public static void main(String[] args)
      {
        Person test;
        test = new Person();
    
        test.name = "Mary";
        test.telephoneNumber = "01234 567890";
    
        test.print();
      }
    }
    

    If I did this, the test.print(); would produce the output:

    mary 01234 567890
    

    However, I know this is considered poor coding. Variables should be private inside a public class, as we don't want to allow people to see how this information is stored or to be able to edit information without authorisation.

    So now, I'll edit the Person class to declare the two Strings private and add get and set methods, like so:

    private String name;
    private String telephoneNumber;
    
    public void setName (String name)
    {
      this.name = name;
    }
    
    public void getName()
    {
      return name;
    }
    
    // same code for telephone methods.
    

    Now, in the main class, I would change the methods of setting name and telephone to the following:

    mary.setName("Mary");
    mary.settelephoneNumber("01234 567890");
    

    According to the lecture notes I'm following, this is more efficient (although could be made even more efficient by adding in a Person() method to allow for instantiation etc.)

    However, I'm struggling to see why this is better.
    In the former method of doing things, the user could directly access the variables. But even though by hiding the variables they can't directly access them, the user can indirectly access and modify them which produces the exact same outcome.

    Why is it that this is preferred and what no doubt silly thing am I missing/overlooking?