4

I have been coding Java for about 4 months. I just started coding android games with the guide of an intro book. In the book, they do not encapsulate any attributes of classes.

Ex.

public class GameObject{
    public Vector position;
    public float angle;

    public GameObject(float angle, Vector position){
...

I was always told that encapsulation of attributes was good practice: only allow access to the private attributes through getter and setter methods.

Could any programmers with more experience than me tell me which way is the "proper" coding way of creating attributes? And of course why please?

And then a follow up: should I always encapsulate private attributes of a class and provide getter and setter methods, or are there situations where public attributes are okay?

ChrisMcJava
  • 2,145
  • 5
  • 25
  • 33
  • 2
    _Should I be using private attributes with getter and setter methods or public attributes_ Yes, I would say you should always use getter and setter methods and avoid public fields. – Pradeep Simha Aug 09 '13 at 06:04
  • In case you're wondering why your book might have done that (or why anyone would do that), Google has recommended (for games on very early versions of Android) for scrapping the getter/setter paradigm because of method overhead. Now that Android is so advanced, this practice is discouraged. See http://www.youtube.com/watch?v=U4Bk5rmIpic at 0:37:10 where Chris Pruett recommended using public fields. – Prime Aug 09 '13 at 06:34

5 Answers5

13

Encapsulation is one of the core concepts of object oriented programming. Using getters and setters, is always, in my opinion good practice. One thing you should avoid is to have external entities mess with the internal structure of your class at will.

Typical example, consider having a dateOfBirth parameter. With a setter and getter you can have a small validation process, making sure that the user was not born in the future, or is impossibly old. You can also use the setter to update some other fields, such as age.

This minor validation can also enhance code re-usability since you do not need to have to make this check in any other class which invokes these getters and setters.

npinti
  • 51,780
  • 5
  • 72
  • 96
4

If we'll put the puristic view aside, we're left with two good reasons to use getters and setters -

  1. It reduces the amount of code change you'll have to do in the future if you'd like to modify your behaviour. Consider the following cases you're suddenly required to make - validate some input, make some field calculated or have it affect other fields when changed, restrict the scope of get or set operations or make them uneven, modify the behaviour of the field in some inherited class or store the field in some bizarre manner. If you already have getters and setters in place - these changes cost you nothing besides the change itself. If not, you'll have to modify every usage of the fields in your project.

  2. It allows you to do implement interfaces which require a getter or setter.

Vadim
  • 2,847
  • 15
  • 18
3

In most cases you should not think of a class as a set of attributes that you operate on externally, but as an entity that provides certain services to the application. Most attributes of the class will end up being private and not having get or set methods.

There are exceptions though: for example in some settings you will find classes that only hold values and have little or no logic themselves. The usual rule for these kinds of classes is to make fields private and provide get and set methods because once you make something public and some other class depends on it you can't change it. For example you may want to ensure that the value of a particular field is never null or do some other validation; if you used a set method you could add the check there, but if the field is public there's nothing you can do. Another example: you may want to change the field type to do some optimization, but if the field is public, there's nothing you can do.

All rules are meant to be broken though. If you know that you will never need get and set methods there's not much point in adding them. Some people may complain about "lack of encapsulation" but if every attribute of the class can be read and written from the outside anyway where's the encapsulation?

Joni
  • 108,737
  • 14
  • 143
  • 193
0

Encapsulation gives more flexibility. It gives you more control, hides implementation details. You can decrease class mutability just without providing set methods. Getters and setters can have additional logic. It's easier to change class implementation without needless to change public API (getters and setters are part of public API).

DraggonZ
  • 1,057
  • 1
  • 16
  • 22
0

Accessors/getters - public methods that are used to inspect the value of instance variables For clients to be able to use a class, implementers of an ADT will often need to provide one or more public functions that allow the user to "see" (inspect) the current values of the private instance variables of an object. These "read-only" type of methods are called accessor functions.

E.g., Two appropriate accessor functions of a class TwoDice are getDice1() and getDice2() which can be used to find the current value of one of the dice. The definition for getDice1() is:

  public int getDice1()
   {
      return dice1 ;
   }

with a similar definition for getDice2(). We can use these functions to store the value of the first die in the integer variable valueOfDie1 as shown below:

   TwoDice roll = new TwoDice() ;
   int valueOfDie1 = roll.getDice1() ;

In the method call roll.getDice1(), the object roll is the current object (the object for which the method is called) so that applying getDice1() to this object will return the value roll.dice1.

Mutators /Setters - Public methods that are used to alter the value of an instance variable. Mutators should include data validation to ensure the values of instance variables do not exceed their permitted range. E.g, The TwoDice class has the interesting property that once a TwoDice object has been created, its value cannot be changed - no public methods have been provided to allow client code to do so. Such objects are said to be immutable which means they cannot be modified once they have been created. A number of Java's own classes has this property of providing only immutable objects - two such examples being the String and Color classes.

Class designers often provide what are called mutator or setter methods to enable client code to modify the value of an object. This is potentially dangerous as it may be seen to compromise the security of private data. It is therefore imperative that the implementer of an ADT provide appropriate data validation to ensure that the value of an attribute (instance variable) is set properly within the bounds of its allowable values. Appropriate mutator methods for our TwoDice class are setDice1( int n ) and setDice2( int n ), and the definition of the first of these is given below:

 public void setDice1( int n )
   {
      assert (n >= 1) && (n <= 6) : "value of dice1 out of range: " + n ;
      dice1 = n ;
   } 

Of interest here, is the use of an assertion which, if it evaluates to false, results in program execution being terminated.

Ushani
  • 1,199
  • 12
  • 28