> Manuales > Teoría de la Programación Orientada a Objetos

Qué son los miembros de clase, definición y ejemplos de elementos static: métodos y atributos de clase, o estáticos, en la programación orientada a objetos.

Métodos y atributos static en Programación Orientada a Objetos

En el Manual de la Teoría de la programación orientada a objetos estamos revisando diversos conceptos y prácticas comúnmente usadas en este paradigma de la programación. Ahora le toca el turno a "static".

Seguramente lo has visto en alguna ocasión en algún código, pues se trata de una práctica bastante común. Con "static", un modificador que podemos aplicar en la definición de métodos y atributos de las clases, podemos definir estos elementos como pertenecientes a la clase, en lugar de pertenecientes a la instancia. A lo largo de este artículo queremos explicar bien qué es esto de los elementos estáticos "static" o también llamados elementos "de clase".

Qué es static

La definición formal de los elementos estáticos (o miembros de clase) nos dice que son aquellos que pertenecen a la clase, en lugar de pertenecer a un objeto en particular. Recuperando concetos básicos de orientación a objetos, sabemos que tenemos:

En las clases defines que tal objeto tendrá tales atributos y tales métodos, sin embargo, para acceder a ellos o darles valores necesitas construir objetos de esa clase. Por ejemplo, una casa tendrá un número de puertas para entrar, en la clase tendrás definida que una de las características de la casa es el número de puertas, pero solo concretarás ese número cuando construyas objetos de la clase casa. Un coche tiene un color, pero en la clase solo dices que existirá un color y hasta que no construyas coches no les asignarás un color en concreto. En la clase cuadrado definirás que el cálculo del área es el "lado elevado a dos", pero para calcular el área de un cuadrado necesitas tener un objeto de esa clase y pedirle que te devuelva su área.

Ese es el comportamiento normal de los miembros de clase. Sin embargo, los elementos estáticos o miembros de clase son un poco distintos. Son elementos que existen dentro de la propia clase y para acceder los cuales no necesitamos haber creado ningún objeto de esa clase. Osea, en vez de acceder a través de un objeto, accedemos a través del nombre de la clase.

Ejemplos de situaciones de la vida real donde tendríamos miembros estáticos

De momento así dicho queda un tanto abstracto. Pero antes de ponerse con ejemplos concretos de programación donde hablemos de la utilidad práctica de los miembros estáticos sea bueno tratar de explicar estos conceptos un con situaciones de la vida real.

Por ejemplo, pensemos en los autobuses de tu ciudad. No sé si es el caso, pero generalmente en España todos los autobuses metropolitanos tienen la misma tarifa. Yo podría definir como un atributo de la clase AutobúsMetropolitano su precio. En condiciones normales, para acceder al precio de un autobús necesitaría instanciar un objeto autobús y luego consultar su precio. ¿Es esto práctico? quizás solo quiero saber su precio para salir de casa con dinero suficiente para pagarlo, pero en el caso de un atributo normal necesariamente debería tener instanciado un autobús para preguntar su precio.

Pensemos en el número "Pi". Sabemos que necesitamos ese número para realizar cálculos con circunferencias. Podría tener la clase Circunferencia y definir como atributo el número Pi. Sin embargo, igual necesito ese número para otra cosa, como pasar ángulos de valores de grados a radianes. En ese caso, en condiciones normales sin atributos de clase, necesitaría instanciar cualquier círculo para luego preguntarle por el valor de "Pi". De nuevo, no parece muy práctico.

Nota: Ojo, porque en el caso del número Pi, su valor será siempre constante. Podríamos en esa caso usar constantes si nuestro lenguaje las tiene, pero los atributos estáticos no tienen por qué ser siempre un valor invariable, como es el caso del precio de los AutobusesMetropolitanos, que sube cada año.

Con esos tenemos dos ejemplos de situaciones en las que me pueden venir bien tener atributos "static", o de clase, porque me permitirían consultar esos datos sin necesidad de tener una instancia de un objeto de esa clase.

En cuanto a métodos, pensemos por ejemplo en la clase Fecha. Puedo intentar construir fechas con un día, un mes y un año, pero puede que no necesite una fecha en un momento dado y solo quiera saber si una fecha podría ser válida. En situaciones normales debería intentar construir esa fecha y esperar a ver si el constructor me arroja un error o si la fecha que construye es válida. Quizás sería más cómodo tener un método vinculado a la clase, en el que podría pasarle un mes, un día y un año y que me diga si son válidos o no.

Cómo definir y usar miembros estáticos

Esto ya depende de tu lenguaje de programación. Generalmente se usa el modificador "static" para definir los miembros de clase, al menos así se hace en Java o PHP, C#, pero podrian existir otros métodos en otros lenguajes.

Nota: El código que verás a continuación no es de uno u otro lenguaje. No es mi objetivo explicar Java, PHP, C#, etc. sino ver en pseudo-codigo rápidamente una posible implementación de el uso de static. Es parecido a Java, pero le he quitado algunas cosas que dificultan el entendimiento de los ejemplos. Tampoco es PHP, porque no he metido los $ de las variables y el uso del acceso a variables estáticas se hace con el operador :: que me parece muy feo y que complica la lectura y comprensión de los ejemplos. Tendrás que consultar la documentación de tu propio lenguaje para ver cómo se hace en él, aquí lo que quiero que queden claros son los conceptos nada más.

class AutobusMetropolitano {
	public static precio = 1.20;
}

Podrás observar que en la definición de la clase hemos asignado un valor al precio a la hora de declarar ese atributo de clase. Esto es condición indispensable en muchos lenguajes, puesto que si existe ese atributo debería tener un valor antes de instanciar el primer objeto. Osea, no es como los atributos normales, que les podemos asignar valores a través del constructor.

Luego podríamos acceder a esos elementos a través del nombre de la clase, como se puede ver a continuación:

if(1.5 >= AutobusMetropolitado.precio){
	//todo bien
}

Ese código sería en el caso que estés accediendo al atributo estático desde fuera de la clase, pero en muchos lenguajes puedes acceder a esos atributos (o métodos) desde la vista privada de tus clases (código de implantación de la clase) a través de la palabra "self".

class AutobusMetropolitano {
	static precio = 1.20;
	//...

	public function aceptarPago(dinero){
		if (dinero < self.precio){
			return false;
		}
		// ...
	}
}

En el caso de los métodos estáticos la forma de crearlos o usarlos no varía mucho, utilizando el mismo modificador "static" al declarar el método.

class Fecha{
	//... 
public static function valida(ano, mes, dia){
		if(dia >31)
			return false;
		// ...
	}
	//...
}

Ahora para saber si un conjunto de año mes y día es válido podrías invocar al método estático a través del nombre de la clase.

if(Fecha.valida(2014, 2, 29)){
	// es valida
}else{
	// no es valida
}

Como en el caso de los atributos de clase, también podrías acceder a métodos de clase con la palabra "self" si estás dentro del código de tu clase.

Miembros estáticos son susceptibles de hacer "marranadas"

No quiero dejar este artículo sin aprovechar la oportunidad de explicar que los miembros estáticos deben estár sujetos a un cuidado adicional para no cometer errores de diseño.

En ocasiones se tiende a usar los métodos estáticos para agregar datos a modo de variables globales, que estén presentes en cualquier lugar de la aplicación a partir del nombre de una clase. Esto nos puede acarrear exactamente los mismos problemas que conocemos por el uso de variables globales en general.

En cuanto a métodos estáticos a veces se usan las clases como simples contenedores de unión de diferentes métodos estáticos. Por ejemplo la clase Math en Javascript, o incluso Java, que tiene simplemente una serie de métodos de clase. Usarlos así, creando métodos estáticos en la clase, sin agregar más valor a la clase a través de métodos o atributos "normales" es caer en prácticas similares a las que se vienen usando en la programación estructurada. Dicho de otra manera, es usar la Programación Orientada a Objetos sin aprovechar los beneficios que nos aporta.

Miguel Angel Alvarez

Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...

Manual