Properties are a feature of certain object-oriented programming languages that allow defining getter and setter methods in a more concise and readable way.
Managing access and modification of class properties is fundamental for data integrity. Traditionally, getter
and setter
methods are used for this, as 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 private fields of a class as if they were public variables, while internally methods are used to get or set the value.
Other than that, they are just “syntactic sugar” for creating and using getter
and setter
methods, in a way that is more comfortable for the programmer.
Practical case
Suppose we have a class Person
that has a private variable name
. Let’s convert this variable into a property.
- stringName
The details will change from one language to another. At the end, I will provide examples in different languages. 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 said in this case varies greatly from one language to another, the important thing is that:
- We have created a property
Name
- Two
getter
andsetter
methods 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. Thus, 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 private fields of a class.
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 the behavior of properties 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, getter and setter methods can be used to interact with private fields of an object.
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 access and modification 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 us to have the benefits of getter
and setter
methods, with the ease of use of a variable.
The only advice to keep in mind is the same we saw when looking at getter
and setter
methods. That is, primarily the methods should be short and simple.
No heavy, blocking tasks, or side-effects should be performed within a property. The code inside the set
and get
methods of a property should be kept to a minimum.
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 need to do something “heavier,” an independent method should be created (for example, GetFromDatabase()
) that clearly indicates the effect that its execution will have.