Using getters and setters (or properties in some languages) is common practice because they promote encapsulation, one of the four principles of object oriented programming. The idea is that an object should have control over its own properties or members, and that outside classes should not be able to directly manipulate its properties or members.
You asked specifically about the internal representation of an object. Java, for instance, passes its members by value when you call a get function, but you are accessing the member directly with dot notation. For example take the following class:
public class Person {
public String name = "John";
public String getName() {
return name;
}
}
In this circumstance you could access the name
member of the Person
class through the getName()
method, or you could access it through dot notation. If you use the getName()
method then you can't inadvertently change the value of the name
member. For example:
public static void main(String[] args) {
Person person = new Person();
String name = person.getName();
name = "Gary";
Sysetm.out.println(person.getName());
}
Will produce the output John
, whereas the following:
public static void main(String[] args) {
Person person = new Person();
person.name = "Gary";
Sysetm.out.println(person.getName());
}
Will produce the output Gary
.
The accepted practice for handling this person class is to use encapsulation, and set a private access modifier for its member, like so:
public class Person {
private String name = "John";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Now you can explicitly set the name member to whatever you would like using the setName
method, but you will never be able to inadvertently change the name member by using dot notation.
Furthermore, there will often be times when you will want to do something with the member before it is returned or before it is set. A simple example would be the following:
public class Person {
private String name = "John";
public String getName() {
return name;
}
public void setName(String name) {
// null values are not allowed, and a name must be at least two characters long
if (name == null || name.length() < 2) {
return;
}
// name must be capitalzed
name = name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase();
this.name = name;
}
}
In summation, we do it this way because encapsulation makes code cleaner, more predictable, and more maintainable. I hope this helps!