• Post Reply Bookmark Topic Watch Topic
  • New Topic

Modifying instance variables  RSS feed

 
suresh midde
Greenhorn
Posts: 25
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I would like to know the difference between way of setting instance variable in the clases ClassA, ClassB, assuming that these classes are in the same package as Base class. I heard that its a bad way of encapsulation




Regards
Suresh Midde

[Edit - added code tags - MB]
 
Stephan van Hulst
Saloon Keeper
Posts: 7991
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I would always avoid making fields protected or public. When you have another class that's in a different package, it should interact with the first one through methods.

If the classes are in the same package, and the classes are closely related, there's no problem in making the field package private and accessing it directly from the second class. It's preferable to use methods though.
 
Manoj Kumar Jain
Ranch Hand
Posts: 198
Java Linux Oracle
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think this is good practice is to keep the instance variable private and access them through the public getter and setter methods exposed by the class. As it keeps the data safe from unexpected modification also like, the variable "age" that you defined can't be a negative no. but if you set that instace variable directly by
Base b = new Base();
b.age = -30;
you can assign a negative value to age. Which might not be correct (depends upon your business logic)

But if you accessing the variable "age" by the setAge method you can place a validation/logic in the getter/setter method.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
suresh midde wrote:I would like to know the difference between way of setting instance variable in the clases ClassA, ClassB, assuming that these classes are in the same package as Base class. I heard that its a bad way of encapsulation

And it is, for all the reasons the others have given. That said, I'm not a huge fan of providing getters and setters for everything either (especially the latter).

An object should know how to change its own state, and should provide methods consistent with doing that. This article contains a good explanation of what I mean.

On a much more basic level, I don't really see the point of an 'age' field at all. Age is a derived value, probably based on a birthdate or creation date that doesn't change, viz:no need for a setter of any kind.

What the others have described are basic data-hiding techniques. Proper encapsulation comes from hiding the implementation from the user; and it's not well served by tons of getters and setters.

My two-penn'orth.

Winston
 
dennis deems
Ranch Hand
Posts: 808
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:I would always avoid making fields protected or public. When you have another class that's in a different package, it should interact with the first one through methods.

If the classes are in the same package, and the classes are closely related, there's no problem in making the field package private and accessing it directly from the second class. It's preferable to use methods though.


I don't understand your aversion to protected access. Can you explain your reasons?
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I second Winston's comments about getters and setters. You don't want to just add them as a matter of course for every variable.

In addition, let's say you had a good reason to provide a setAge() method, and that it should only take non-negative values. The following is still wrong.

Manoj Kumar Jain wrote:
But if you accessing the variable "age" by the setAge method you can place a validation/logic in the getter/setter method.


You don't want to just blindly turn invalid values into some default. Passing a negative value is a bug in the calling code, and we should not just gloss over it. The correct approach is to throw an unchecked exception:

 
Saurabh Pillai
Ranch Hand
Posts: 541
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:That said, I'm not a huge fan of providing getters and setters for everything either (especially the latter).


getters/setters give you more control. Let's say you have designed a class and it is being used an API or something. According to you, particular fields (let's say an int) should not have -ve value. so setter is the place where you can stop the assignment and further propagation.

I agree with Manoj's example. Also, age is just a place holder in this example. It can be any business value.

 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Saurabh Pillai wrote:
Winston Gutkowski wrote:That said, I'm not a huge fan of providing getters and setters for everything either (especially the latter).


getters/setters give you more control. Let's say you have designed a class and it is being used an API or something. According to you, particular fields (let's say an int) should not have -ve value. so setter is the place where you can stop the assignment and further propagation.


You misunderstand. He's not saying we should skip getters and setters and just make the variables public. He's saying the variables shouldn't be exposed at all in many cases. No direct get/set methods. The class manipulates the variables directly as it needs to use them, but exposure of those variables to the outside world only occurs indirectly, via business methods. For example, an ArrayList might have a size member that indicates how much of the backing array is used. You wouldn't want a setter for that.


I agree with Manoj's example. Also, age is just a place holder in this example. It can be any business value.


What do you agree with? Setter instead of direct access. Okay, that's fine, although often no setter or getter is even better. And, as I stated earlier, it should throw an exception for an invalid input.
 
Saurabh Pillai
Ranch Hand
Posts: 541
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:What do you agree with? Setter instead of direct access. Okay, that's fine, although often no setter or getter is even better. And, as I stated earlier, it should throw an exception for an invalid input.

Yup, it should definitely throw an exception and it can be done from setter itself.

He's saying the variables shouldn't be exposed at all in many cases. No direct get/set methods. The class manipulates the variables directly as it needs to use them, but exposure of those variables to the outside world only occurs indirectly, via business methods.

OK, I understand your point. not fully.

although often no setter or getter is even better

But we still might have Bean classes? A user object maybe, most of the time you manipulate them outside of the bean class itself.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Saurabh Pillai wrote:
Jeff Verdegan wrote:
although often no setter or getter is even better

But we still might have Bean classes? A user object maybe, most of the time you manipulate them outside of the bean class itself.


Yes, beans can still exist and be useful. Nobody is saying to get rid of all setters and getters everywhere forever and ever. The point is that many beginners often add set/get methods for every member variable in every class, not realizing that in many cases it is not appropriate to expose the variable directly. Unless I'm writing a DTO, I start with no setters or getters, and only add one when a specific legitimate need arises.

 
Stephan van Hulst
Saloon Keeper
Posts: 7991
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dennis Deems wrote:I don't understand your aversion to protected access. Can you explain your reasons?


Protected is pretty much the same as public in that it exposes all the class' guts for the world to see. The API can no longer guarantee the safe use of various methods, because the types can not enforce invariants on their internal representation.

This is not the case for package private fields, because they never get exported with the API. In this case, the entire package works together to enforce invariants.
 
Saurabh Pillai
Ranch Hand
Posts: 541
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote: Unless I'm writing a DTO, I start with no setters or getters, and only add one when a specific legitimate need arises.


+1. only on need basis. and I guess this is the answer to Dennis' question, I don't understand your aversion to protected access. Can you explain your reasons?. You broader the scope if you need it.
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Saurabh Pillai wrote: . . . You broader the scope if you need it.
No, you keep the scope of fields as small as possible. Make all fields private until you see a need for less restrictive access. Stphans’s example about classes in the same package is an example of a special case where package-private access is appropriate; treat the entire package as if it were a single class. But you should not allow other classes to meddle with your class’s interior. Such exposure of implementation details leads to tight coupling, and, as Stephan said more recently, permits other classes to violate a class invariant. He is right to object to protected or public access. And I agree with Winston about not putting setters and getters on every method on spec., even though that may be required for the bean pattern.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:No, you keep the scope of fields as small as possible. Make all fields private until you see a need for less restrictive access.

And I'd say even if you don't (I haven't found a need to in 10 years of using Java). Unless your entire hierarchy is self-contained - ie, it presents no publically extendable classes (which is pretty tough to do) - you're opening yourself up to a world of hurt by having protected attributes...or reams of redundant validation checks. If a subclass absolutely must have access to a single field (as opposed to business logic), let it use a protected getter or setter.

Sorry to the experts - I'm a bit of a Puritan about this.

The only possible exception is a protected final field; and even that is restrictive, because you can never safely remove the final once the class has been published.

@Saurabh: Did you read the article I posted? It's very good, and might answer some of your questions.

Winston
 
Campbell Ritchie
Marshal
Posts: 56570
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote: . . . Did you read the article I posted? It's very good . . .

Winston
Yes, I did. It is a good article, reminding us of the responsibilities of an object.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!