Working with class attributes directly

I heard that it is not a good idea to work with class attributes directly, using setters and getters instead. Can someone tell me why?

+4
source share
6 answers

Oddly enough, the Wikipedia article on this subject provides a good guide: http://en.wikipedia.org/wiki/Accessor

In short, a class must use mutator methods (getters, seters, etc.) to validate input before it is kept confidential. This ensures that the class can always be used elsewhere in the code.

In contrast, if an attribute is available worldwide, anyone can change it. If you have, for example, a string that must be of a certain format, and someone adds the wrong value, errors may occur.

+6
source

In short, if you code interfaces (containing getters and setters in a private field), you can change any object that matches the interface. External links to object fields mean that external users are aware of the implementation. This creates a connection between the consumer of the object and the implementation of the object, which in this case is bad.

Today your name field can be saved as a String , but next year you can update it to a more interesting type or get information from somewhere else or something ... who knows? Using a field prevents this. Using accessories allows you to change the implementation, but you want to. This is a more important principle than you think.

You can find this: Interface Coding?

+5
source

It just depends; For simple changes inside a class (bool member), it's probably faster to just change it. If it's a little trickier (MyDate) then you might need to do some checking.

Most people keep member data private, so get / set or methods should be used to modify this data outside the class.

+1
source

This is an agreement, albeit a strong one.

It is used by the JavaBean specification to offer a workaround to the fact that Java has no properties.

It allows you to express intent only read / write or read / write.

It is very convenient to place a breakpoint in the setter to understand why the attribute was changed without changes.

As already mentioned, interfaces cannot contain attributes, but accessors can define.

Sometimes you need to create β€œvirtual” attributes, a classic example is complex numbers in which you have the x and y attributes, and also suggest a mod and angle through computation in setters and getters.

Many APIs rely on this convention to infer the meaning of your class through reflection.

The entire IDE can now generate them automatically so that they don't hurt my fingers as much as in the past.

+1
source

There are two classic reasons why you want to deny external access to fields (attributes). They are usually discussed in the introductory OO programming classes.

  • If the underlying data is private, you can change the implementation in the class. For example, suppose you store a complex number as the real and imaginary part. Then you decided that you want to change this to save Z and theta (magnitude and angle). If you set fields, this change will break any classes that interact with it. If you used accessors, then you could implement getReal () and getImaginary () in terms of Z and theta and not break anything.
  • You can add other operations to recipients and (especially) setters. For example, you can track how many changes are made to a field, or update another field that is synchronized with it, but only if you have forced any class that wants to change the field to go through an accessory to do this. With a public field, you have no chance of it.
+1
source

In reality, this means that Java does not respect the principle of Uniform Access. That is, the client code for changing the field value (for example, obj.field = newValue ) is very different from the code for calling the installer (for example, obj.setField(newValue) ).

If you start with a public field and then decide that you really need a private member (for example, to add verification or change the basic implementation of a member), all of your client code will break. As a result, you need to use a setter, not a public field, if it is likely that you will need additional features provided by accessories. The end result is a lot of unnecessary code:

 public class Person { private String _firstName; private String _lastName; public Person(String firstName, String lastName) { _firstName = firstName; _lastName = lastName; } public String getFirstName() { return _firstName; } public void setFirstName(String name) { _firstName = name; } public String getLastName() { return _lastName; } public void setLastName(String name) { _lastName = name; } } 

Languages ​​that respect UAP, such as Scala , often use public fields instead of getters / seters. The above class in Scala, for example, writes:

 class Person(var firstName: String, var lastName: String) // example client code: val p = new Person("John", "Smith"); p.lastName = "Brown"; 

If I decide that I need a check, I can replace this with:

 class Person(firstName: String, lastName: String) private var _firstName = validate(firstName); private var _lastName = validate(lastName); // getters def firstName: String = _firstName def lastName: String = _lastName // setters def firstName_=(name: String): Unit = { _firstName = validate(name); } def lastName_=(name: String): Unit = { _lastName = validate(name); } // validation @throws(classOf[IllegalArgumentException]) private def validate(name: String): String = { // ... validation code ... name } } // and client code doesn't break! val p = new Person("John", "Smith"); p.lastName = "Brown"; 
+1
source

All Articles