Properties are a feature of certain object-oriented programming languages that allow you to define getter and setter methods in a more concise and readable way.
Managing access and modification of a class’s properties is fundamental for data integrity. Traditionally, this is done using the getter and setter methods we saw in the previous article.
Many modern programming languages offer a more intuitive and convenient alternative in the form of properties.
Properties allow users to access a class’s private fields as if they were public variables, while internally using methods to get or set the value.
Otherwise, they are essentially “syntactic sugar” for creating and using getter and setter methods, in a way that is more convenient for the programmer.
Practical Case
Suppose we have a Person class that has a private variable name. Let’s convert this variable into a property.
- stringNombre
The details will vary from one language to another. I’ll put examples in different languages at the end. For example, in C# it would be done like this.
class Person {
string Name { get; set; }
}
Beyond the way of defining it, which as I say varies a lot from one language to another in this case, the important thing is that:
- We have created a property
Name - Two
getterandsettermethods have been created for us - There is a private internal variable, which we don’t even see
To use our property, we simply use it as if it were a public variable, with =.
Person person = new Person();
person.Name = "Luis"; // invokes the setter
var name = person.Name; // invokes the getter
Internally, the appropriate getter and setter methods will be invoked, without us having to do anything else. So we see that we maintain the advantage of methods, with the simplicity of using a variable.
Examples in Different Languages
Let’s see how the concept of Property is implemented in different programming languages.
In C#, properties are defined using the get and set keywords to allow access and modification of a class’s private fields.
public class Person
{
private string name;
// Property
public string Name
{
get { return name; }
set
{
if (!string.IsNullOrEmpty(value))
{
name = value;
}
}
}
}
// Usage
Person person = new Person();
person.Name = "Luis";
Console.WriteLine(person.Name);
In C++, the concept of properties is not as integrated into the language as in other modern object-oriented languages. However, the Microsoft compiler (MSVC) provides a specific extension called __declspec(property) that allows simulating property behavior similar to what we find in C#.
class Person {
private:
std::string name;
public:
void setName(const std::string& value) {
if (!value.empty()) {
name = value;
} else {
throw std::invalid_argument("Name cannot be empty");
}
}
std::string getName() const {
return name;
}
__declspec(property(get = getName, put = setName)) std::string Name;
};
int main() {
Person person;
person.Name = "Luis";
std::cout << person.Name << std::endl; // "Luis"
return 0;
}
In JavaScript, accessor methods (getters) and mutator methods (setters) can be used to interact with an object’s private fields.
class Person {
constructor() {
this._name = '';
}
// Property
get name() {
return this._name;
}
set name(value) {
if (value) {
this._name = value;
}
}
}
// Usage
const person = new Person();
person.name = "Luis";
console.log(person.name);
In TypeScript, properties can be defined using the get and set syntax.
class Person {
private _name: string;
// Property
get name(): string {
return this._name;
}
set name(value: string) {
if (value) {
this._name = value;
}
}
}
// Usage
const person = new Person();
person.name = "Luis";
console.log(person.name);
In Python, @property and @name.setter decorators can be used to define properties with accessor and mutator methods.
class Person:
def __init__(self):
self._name = None
# Property
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if value:
self._name = value
# Usage
person = Person()
person.name = "Luis"
print(person.name)
Best Practices Tips
As we can see, properties are all advantages. They allow you to have the benefits of getter and setter methods, with the ease of use of a variable.
The only tips to keep in mind are those we already saw when looking at getter and setter methods. That is, mainly the methods must be short and simple.
No heavy, blocking tasks, or tasks with side-effects inside a property. The code inside the set and get methods of a property should be as minimal as possible.
In most cases, only return or modify the value of the property. At most, what is necessary to validate and maintain the integrity of your object’s data.
If you have to do something more “heavy”, you need to create an independent method (for example, GetFromDatabase()) that clearly indicates the effect its execution will have.
