简体   繁体   中英

Use getters and setters in class that defines variables?

I have been reading about getters and setters and I have a question. Are getters and setters supposed to be used when accessing the variables in the class that declared the variables? It seems like there is no need for getters and setters here because it doesnt matter that the variable is private, the class that declared it will always have access to it....?

Or are getters and setters only supposed to be used when external classes want to access these variables?

While the language doesn't require you to do so, it is good practice to use getters and setters when accessing private fields that are exposed through getters and setters. In some cases I would even go so far as to say that it makes sense to use them even for internal properties that are not directly exposed (yet).

The reason it is good practice to do so is because it isolates the code that reads and modifies the private fields to a single set of methods. That way you can later provide extra validation, or even change the way the property is stored internally without having to change too many places.

An example of a change might be a class that exposes, through getter (accessor) / setter (mutator) methods, a certain property that is initially stored as a private field in that class. Later you realise that you need to use a different storage repository for that property - maybe read it from a file, or from a database etc. At that point if you've only used the methods to access and modify the property you can simply change the code of the accessor and mutator methods to implement the change.

Another example would be instances when the class is extended. It provides better encapsulation.

And even for testing it makes sense to abstract access to the private "storage repository" for a logical property.

Note: I'm referring to the concept of the private member you're exposing as a property of the class even though Java doesn't necessarily refer to them as such.

Finally, I can't stress enough that my recommendation to use methods instead of directly accessing the private member is just that: a recommendation . It's considered by many to be good practice and as such I recommend you follow, but by all means feel free to not follow if you have a good reason not too!

The simple answer is: It's up to you.

There is a school of thought that says you should always use the accessors and only ever go direct to the variable in the accessor and never outside it. This ensures that whatever you implement in the accessors is reliably triggered.

There is another school of thought that says that the accessors are there for the public contract of your class, whereas internally in your class you are free to do what you want. Sometimes you may want to set a value without triggering whatever other things you've implemented in the accessors.

(There used to be an argument, some years ago, about the performance aspect of using accessors where you didn't actually "need" to, but with today's JIT compilation methods and such, that's no longer a factor at all.)

It depends.

If the getter or setter is not final, and if it is intended to be overridden in potential subclasses, it might make sense to call it even from the class itself, in order to avoid bypassing the additional behavior added by the subclass to the accessor.

For example, suppose a subclass wants to fire an event each time some property is changed. To do that, it overrides the setter for this property. But if some other method of the superclass modifies the property directly, without using the setter, then the event won't be fired. In this case, it makes sense using the setter from the base class.

There's no simple answer for that. Depends on what your accessors do. If they are just there to access the variable, then it doesn't really matter... if they do some logic, then it depends if you want to use that logic inside your class or not.

There are plenty of examples where you wouldn't want to access the variable using the property from inside the class, but not let an external entity access that variable without going through your property accessors.

That said, my way of seeing it is: unless you have a valid reason not to go through the logic of the accessor, use them.

IT can also depend on the environment that you are working in. For exapmle if you are doing Java programming in the Android environment, direct access is encouraged, over getters/setters. In other environments, the getters/setters may be encouraged for maintainability.

From the Android developer docs at http://developer.android.com/guide/practices/design/performance.html

Avoid Internal Getters/Setters

In native languages like C++ it's common practice to use getters (eg i = getCount()) instead of accessing the field directly (i = mCount). This is an excellent habit for C++, because the compiler can usually inline the access, and if you need to restrict or debug field access you can add the code at any time.

On Android, this is a bad idea. Virtual method calls are expensive, much more so than instance field lookups. It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.

Without a JIT, direct field access is about 3x faster than invoking a trivial getter. With the JIT (where direct field access is as cheap as accessing a local), direct field access is about 7x faster than invoking a trivial getter. This is true in Froyo, but will improve in the future when the JIT inlines getter methods.

Inside a class I use the private member. If it turns out I need the extra logic in the accessors to run as well from within the class, then I move them out in to another. Helper, internal, a parent, anything but leave the ambiguity in the current class.

Issues like tend to proliferate as classes get refactored, and can leave some painful and often hard to see bugs about.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM