So now another class would do this to get the balance (assuming you first created a bankvault object named myBankVault.

Code :

balance = myBankVault.getBalance();

and this to set it

Code :

myBankVault.setBalance(10000000);

How is that an improvement on just declaring the balance variable public and letting other classes just set it directly instead of going through functions? It's sort of like setting up a bank vault, not letting anyone in except one guy named Larry, and Larry will go into the vault and do whatever you want at any time. Maybe there's something I'm missing here, but it doesn't seem like getters and setters and private variables actually do anything but force you to write more code.

September 15th, 2013, 09:53 PM

Junky

Re: So I'm not sure I really get the idea behind private data members vis a vis getters and setters.

The bank would not stay in business long. However we can change withdraw method to check the balance first. If the balance was made public anyone could simply set their balance to some huge amount without actually depositing any money. Getter and setter methods can control access to private values and perform error checks before allowing that access.

September 16th, 2013, 11:48 AM

mstabosz

Re: So I'm not sure I really get the idea behind private data members vis a vis getters and setters.

Right. Duh. Thanks Junky. I didn't occur to me that getters and setters don't HAVE to be just the one line. Seems obvious now.

September 16th, 2013, 12:02 PM

KevinWorkman

Re: So I'm not sure I really get the idea behind private data members vis a vis getters and setters.

Re: So I'm not sure I really get the idea behind private data members vis a vis getters and setters.

@mstabosz Look at it this way. You are right, using getters and setters that simply provide unrestricted access to the variable does not do much. From an educational standpoint, this is an introduction to their use. In future code you will implement more of a body in the method than simply returning/setting the value. There is a link below to a previous post on this topic using a bank example as well.

A fundamental precept of OO systems is that an object should not expose any of its implementation details. This way, you can change the implementation without changing the code that uses the object.

Agreed...

Quote:

It follows then that in OO systems you should avoid getter and setter functions since they mostly provide access to implementation details.

...Show me, I do not see it. So the article continues to say:

Quote:

To see why, consider that there might be 1,000 calls to a getX() method in your program, and each call assumes that the return value is of a particular type. You might store getX()'s return value in a local variable, for example, and that variable type must match the return-value type. If you need to change the way the object is implemented in such a way that the type of X changes, you're in deep trouble.

If X was an int, but now must be a long, you'll get 1,000 compile errors. If you incorrectly fix the problem by casting the return value to int, the code will compile cleanly, but it won't work. (The return value might be truncated.) You must modify the code surrounding each of those 1,000 calls to compensate for the change. I certainly don't want to do that much work.

Is it less work to fix 1000 calls if you used the variable directly? Show me the code to support this claim.

Quote:

Getter and setter methods (also known as accessors) are dangerous for the same reason that public fields are dangerous: They provide external access to implementation details.

What if you need to change the accessed field's type? You also have to change the accessor's return type. You use this return value in numerous places, so you must also change all of that code. I want to limit the effects of a change to a single class definition. I don't want them to ripple out into the entire program.

Again, as stated above, would there be any less work with such a change if getters/setters had not been used?

Quote:

Since accessors violate the encapsulation principle, you can reasonably argue that a system that heavily or inappropriately uses accessors simply isn't object oriented.

The method is public, the implementation (the body of the method) is NOT public. It is encapsulated and protected by the implementation details of the body, vs the unregulated use of an exposed public field.

Page 4:

Quote:

Accessors were created solely as a way to tag certain properties so a UI-builder program or equivalent could identify them. You aren't supposed to call these methods yourself. They exist for an automated tool to use.

Again, the methods provide a layer of security not provided by public access to a variable, and they are supposed to be called by any code using the object. What was this opinion (that you should not call accessors yourself) even based on?

Page 6:

Quote:

Let's pull everything together: You shouldn't use accessor methods (getters and setters) unless absolutely necessary because these methods expose information about how a class is implemented and as a consequence make your code harder to maintain.

Again, the getters and setters provide a layer of protection not available with public access to a variable. Again, show me how it is harder to maintain. Given the "proof" in the article (change int x to long x, used in 1000 places) you have just as much work to do if you make such a change to an object.

Quote:

Getter/setter methods often make their way in code because the coder was thinking procedurally.

Maybe in the code by the author of the article...
Is myObject.getX() any more procedural than myObject.x in your code? If so, post the code, I can not wait to see it.

Overall: If you have not read the article, do not waste your time

September 16th, 2013, 03:14 PM

helloworld922

Re: So I'm not sure I really get the idea behind private data members vis a vis getters and setters.

+1 for jps's recommendations. There is next to no advantage of obj.x over obj.getX() from both performance and abstraction/code style perspectives (side note, I'm sure I'm ruining my reputation completely by talking about these low level performance details and Java at the same time).

Any smart compiler will inline the code if getX() simply returns a member field value. Only debug builds or builds with the most basic of optimizations turned off realistically will omit this optimization, but for these builds you don't care about performance (within reason). In fact, sometimes the return value doesn't need to be tied to an actual field. Why waste space storing a field in every instance when you could just hard-code the calculation/value into getX(), offering the compiler even greater optimization opportunities?

What if you decide later that x and y isn't the ideal method for representing your object? What if angle and radius works better? It's still possible to implement getX() to calculate the value based off of the actual implementation details, but obj.x fixes you into costly re-writes when this situation arises. Adding anything and changing anything private is relatively easy because my code is still completely compatible with previous code. Removing or changing anything which is not private is very difficult because now my code is not guaranteed to work with all previously possible use cases (even obscure ones). Will getX() be less efficient now? Possibly, but the bigger question is will you care? 99%+ of the time the difference is small enough to ignore, and in the last little bit you're stuck with a re-write of the client code either way.

What about cases where a field shouldn't be externally modified, but is paramount that it can be internally modified (e.g. size of an ArrayList)? There are no const-casts in Java so declaring a field final effectively locks its value for all time for everyone. Using accessors means I can provide a public getSize() method, and either internally modify the actual size field, or declare a private setSize() method.

The only advantage I can think of for direct access is you don't have to type a parenthesis pair, and you don't have to define the accessors in the class. But we have tools which can generate accessors for us, and a parenthesis pair is hardly worth complaining over.

September 16th, 2013, 04:18 PM

aussiemcgr

Re: So I'm not sure I really get the idea behind private data members vis a vis getters and setters.

Here is an example of when a getter can save you a lot of trouble (I use this behavior all the time):
Let's say you have a List variable which you do not initialize in your constructor for some reason, but you never want that list to be null. Technically, this does add an extra bit of complexity (compared to simply initializing in the constructor), but I have found uses for it:

Code java:

private List<String> list;/**
* This getter guarentees I will never get a null pointer from accessing the list variable
*/public List<String> getList(){if(list==null)
list =new ArrayList<String>();return list;}

September 16th, 2013, 07:47 PM

helloworld922

Re: So I'm not sure I really get the idea behind private data members vis a vis getters and setters.

I don't like the lazy initialization method because it means my object really isn't really valid at all times, it only kind of looks valid. Internal code could try to access list directly, assume it's not null, then boom. It is also quite an expensive way to retrieve the value: you have to branch just to return a value. Branching is one of the easiest ways to kill your performance, especially when trying to take advantage of modern CPU architectures.

It also has some consequences when it comes to multi-threading, though if you're clever you can probably avoid most of these potential problems.