Language: EN

que-son-metodos-variables-estaticos-en-programacion

What are static variables and methods

Static variables and methods are those that belong to the class itself, rather than to individual instances of the class.

This means that there is a single copy of each static variable or method, shared by all instances of that class.

For example, if you had a Person class and each instance had its own book with its own data, static variables and methods would be a large shared board that everyone can read and write on.

poo-variables-metodos-estaticos

All people share the common board

Static methods are an approach to procedural programming, without straying (much) from object-oriented programming paradigms. Meanwhile, static variables are something similar to “global variables”.

They are also slightly more convenient to use than instance methods, because they do not require creating the instance before using them.

Static variables and methods

Static variables

Static variables belong to the class. This means that there is a single copy of the variable, shared by all instances of the class.

Any method, both instance and static, can potentially access the variables (as long as the access modifiers allow it).

Static variables can be used to store data that should be accessible to all instances, to maintain a global state, or constants.

Static methods

Static methods are functions that belong to the class and not to an instance of the class.

These methods cannot access instance variables or methods directly, because instances do not exist for them. However, they can access other static variables and methods.

Practical case

Let’s go back to the practical case of the Person class that we had when we saw instance variables and methods. This time, we have added a static variable Counter and a static method IncrementCounter as an example.

Person
  • stringName
  • stringDni
  • static intCounter
  • static voidIncrementCounter()

First of all, from anywhere in the code I can access static variables and methods. That is, it is possible to do this from anywhere,

Person.Counter = 12;
Person.IncrementCounter();

Of course, “from anywhere” implies that all instances can equally access the variables. Even in the class definition itself.

In fact, one of the typical examples of static variables and methods is to add a counter that counts the instances we generate from a class. (In the end we will see that this is not a good idea 🙅‍♂️, except to make an example)

If we wanted to do that, we would simply increment the static variable Counter in the constructor of Person.

class Person 
{
	Person()
	{
		Person.Counter++;

		// we could also call the static method
		//Person.IncrementCounter();
	}
}

As I said, as an idea it is not the best in the world, but it illustrates well how we can use static variables and methods from anywhere in the code.

Examples in different languages

Finally, let’s see how different languages implement the concept of static variables and methods.

In C#, static variables and methods are defined using the static keyword.

public class Counter
{
    // Static variable
    public static int Counter;

    // Static method
    public static void IncrementCounter()
    {
        Counter++;
    }
}

// Usage
Counter.IncrementCounter();
Console.WriteLine(Counter.Counter);

In C++, static variables and methods are defined using the static keyword.

#include <iostream>

class Counter {
public:
    // Static variable
    static int Counter;

    // Static method
    static void IncrementCounter() {
        Counter++;
    }
};

// Definition of the static variable
int Counter::Counter = 0;

// Usage
int main() {
    Counter::IncrementCounter();
    std::cout << Counter::Counter << std::endl;
    return 0;
}

In JavaScript, static variables and methods are defined using the static keyword. These variables and methods belong to the class instead of individual instances of the class.

class Counter {
    // Static variable
    static counter = 0;

    // Static method
    static incrementCounter() {
        Counter.counter++;
    }
}

// Usage
Counter.incrementCounter();
console.log(Counter.counter);

In TypeScript, static variables and methods are defined using the static keyword.

class Counter {
    // Static variable
    static counter: number = 0;

    // Static method
    static incrementCounter(): void {
        Counter.counter++;
    }
}

// Usage
Counter.incrementCounter();
console.log(Counter.counter);

In Python, static variables and methods can be simulated using @classmethod decorators and class variables.

class Counter:
    # Static variable
    counter = 0

    # Static method
    @classmethod
    def increment_counter(cls):
        cls.counter += 1

# Usage
Counter.increment_counter()
print(Counter.counter)

Best practices Tips

The million-dollar question with static methods is When do I use a static method and when not? And throughout your life I tell you that you will change several times between loving them and hating them😘.

In principle, my advice is that you avoid static methods and variables whenever possible. The main reason is that you cannot overwrite them, nor can they be easily replaced, and… basically they give you almost no play.

Once your code “hooks” into a static method, you are tied to it forever. That means they will give me maintenance problems in the future, testing, to make mocks… they will give me problems of everything.

MyClass.DoSomething();  // once you put that in, you eat it forever

Also, most of the time it doesn’t make sense to use them. In the example we have given, which is the typical one used, of a counter that counts the number of Person instances created… well that in real life is a mess.

If you are going to do something like that, the logical thing is that you have a higher-level object PersonManager or GroupPerson, or whatever, that contains that information that is normally used in the examples to illustrate static variables and methods.

public class PersonManager
{
	public int Counter;
	
	public Person GeneratePerson() {
		//.. whatever 
	}
}

However, it is also important to note that static methods add simplicity to programs. For example, imagine you are making a library that downloads videos from the Internet. A static method may be easier to use.

// it is easier to use this
VideoDownloader.Download("video_url");

// than this
var videoDownloader = new VidewDownloader();
videoDownloader.Download("video_url");

In short, my advice is to avoid static methods as much as possible. Only if they make sense in the original purpose, which are very isolated functions, and do not require variables or their own information.

The typical example is a function with mathematical functions, where you simply want to have the functions grouped, but basically it is still procedural programming. There, it makes sense for them to be static.

Or, when you want to offer a simpler way for the developer to use a library. And normally always as a shortcut to an alternative method, which offers more functions.