Language: EN

que-son-getters-y-setters-en-programacion

What are getters and setters

The getter and setter methods are methods that allow you to control how the internal state of an object is accessed and modified.

They provide a controlled way to update the internal state of an object, allowing for validations and restrictions on the values that can be assigned.

The getter (from English get) is a method that allows you to access the value of a private or protected property of a class.

On the other hand, the setter (from English set) is a method that allows you to modify the value of a private or protected property of a class.

Both getter and setter methods can include additional logic, such as data transformation or controlled access, before returning the value.

Otherwise, the getter or setter methods are nothing special. It’s simply a naming convention we use. But they remain absolutely normal instance methods.

Practical Case

Suppose we have a class Persona that has a private variable nombre. Creating a getter and setter method for this property is as simple as creating two methods.

  • The method GetNombre() that returns the variable nombre
  • The method SetNombre() that replaces the variable nombre

In other words, something like this,

public class Persona
{
    private string nombre;

    // Getter
    public string GetNombre()
    {
        return nombre;
    }
    
    // Setter
    public void SetNombre(string valor)
    {
        nombre = valor;        
    }
}

As we see, it’s simply a naming convention for two methods that have the minimal logic possible to manage the private variable nombre.

Examples in Different Languages

Let’s see an implementation example in different programming languages,

In C#, getter and setter functions are implemented using conventional methods to access and modify private fields of a class.

public class Persona
{
    private string nombre;

    // Getter
    public string GetNombre()
    {
        return nombre;
    }

    // Setter
    public void SetNombre(string valor)
    {
        if (!string.IsNullOrEmpty(valor))
        {
            nombre = valor;
        }
    }
}

// Usage
Persona persona = new Persona();
persona.SetNombre("Juan");
Console.WriteLine(persona.GetNombre());

In C++, access methods (getters) and modification methods (setters) can be defined to interact with private fields of a class.

#include <iostream>
#include <string>

class Persona {
private:
    std::string nombre;

public:
    // Getter
    std::string getNombre() const {
        return nombre;
    }

    // Setter
    void setNombre(const std::string& valor) {
        if (!valor.empty()) {
            nombre = valor;
        }
    }
};

// Usage
int main() {
    Persona persona;
    persona.setNombre("Juan");
    std::cout << persona.getNombre() << std::endl;
    return 0;
}

In JavaScript, there are no getter and setter functions as in other languages, but they can be simulated using methods to access and modify private fields of an object.

class Persona {
    constructor() {
        this._nombre = "";
    }

    // Getter
    getNombre() {
        return this._nombre;
    }

    // Setter
    setNombre(valor) {
        if (valor) {
            this._nombre = valor;
        }
    }
}

// Usage
const persona = new Persona();
persona.setNombre("Juan");
console.log(persona.getNombre());

In TypeScript, properties can be defined using the get and set syntax to interact with private fields of a class similarly to C#.

class Persona {
    private nombre: string = "";

    // Getter
    getNombre(): string {
        return this.nombre;
    }

    // Setter
    setNombre(valor: string): void {
        if (valor) {
            this.nombre = valor;
        }
    }
}

// Usage
const persona = new Persona();
persona.setNombre("Juan");
console.log(persona.getNombre());

In Python, you can use the @property and @nombre.setter decorators to define getter and setter methods as part of a property.

class Persona:
    def __init__(self):
        self._nombre = ""

    # Getter
    def get_nombre(self):
        return self._nombre

    # Setter
    def set_nombre(self, valor):
        if valor:
            self._nombre = valor

# Usage
persona = Persona()
persona.set_nombre("Juan")
print(persona.get_nombre())

Best Practices Tips

Like almost everything in programming, getter and setter methods are not without some controversy. Some people defend them, while others believe they are not even necessary.

Among the detractors, the main argument is that it doesn’t make much sense to create methods for all variables, just to access them. For that, why not just use the variables directly?

I’ll tell you the classic version in favor of their existence. In theory, the variables of an object should always be private, as they constitute the internal state of the instance.

Access to them should be “controlled,” and for that, there are getter and setter methods. Just as you wouldn’t let just anyone mess with your insides and poke around your kidneys.

In this way, getter and setter methods allow you to hide the internal implementation of a class and expose only what is necessary. This protects the integrity of the data, adds validations, and prevents uncontrolled access.

On the other hand, by accessing through getter and setter methods, I always have a certain freedom to modify and maintain the behavior of a class, for example, in the face of future changes.

Moreover, unlike variables, I can override the behavior of getter and setter methods in child classes. This is a great advantage and also facilitates tasks like testing.

In any case, if you use getter and setter methods, the first rule is to keep them simple and clear. They must be very lightweight functions that perform minimal validation and nothing more.

No reading from a database, performing complicated calculations, or any other heavy task or side effects. Getter and setter methods need to be straightforward and quick.

To alleviate some of the overhead of having to define getter and setter methods for all variables, many languages implement the concept of Properties, which we will see in the next article.