TutorJava Nivel Básico

Cuando se declara una variable miembro como unFloat en MiClase.

class MiClase {
    float unFloat;
}

declara una variable de ejemplar. Cada vez que se crea un ejemplar de la clase, el sistema crea una copia de todas las variables de ejemplar de la clase. Se puede acceder a una variable del ejemplar del objeto desde un objeto como se describe en Utilizar Objetos.

Las variables de ejemplar est�n en constraste con las variables de clase (que se declaran utilizando el modificador static). El sistema asigna espacio para las variables de clase una vez por clase, sin importar el n�mero de ejemplares creados de la clase. Todos los objetos creados de esta clase comparten la misma copia de las variables de clase de la clase, se puede acceder a las variables de clase a trav�s de un ejemplar o a trav�s de la propia clase.

Los m�todos son similares: una clase puede tener m�todos de ejemplar y m�todos de clase. Los m�todos de ejemplar operan sobre las variables de ejemplar del objeto actual pero tambi�n pueden acceder a las variables de clase. Por otro lado, los m�todos de clase no pueden acceder a las variables del ejemplar declarados dentro de la clase (a menos que se cree un objeto nuevo y acceda a ellos a trav�s del objeto). Los m�todos de clase tambi�n pueden ser invocados desde la clase, no se necesita un ejemplar para llamar a los m�todos de la clase.

Por defecto, a menos que se especifique de otra forma, un miembro declarado dentro de una clase es un miembro del ejemplar. La clase definida abajo tiene una variable de ejemplar -- un entero llamado x -- y dos m�todos de ejemplar -- x() y setX() -- que permite que otros objetos pregunten por el valor de x.

class UnEnteroLlamadoX {
    int x;
    public int x() {
        return x;
    }
    public void setX(int newX) {
        x = newX;
    }
}

Cada vez que se ejemplariza un objeto nuevo desde una clase, se obtiene una copia de cada una de las variables de ejemplar de la clase. Estas copias est�n asociadas con el objeto nuevo. Por eso, cada vez que se ejemplariza un nuevo objeto UnEnteroLlamadoX de la clase, se obtiene una copia de x que est� asociada con el nuevo objeto UnEnteroLlamadoX.

Todos los ejemplares de una clase comparten la misma implementaci�n de un m�todo de ejemplar; todos los ejemplares de UnEnteroLlamadoX comparten la misma implementaci�n de x() y setX(). Observa que estos m�todos se refieren a la variable de ejemplar del objeto x por su nombre. "Pero, �si todos los ejemplares de UnEnteroLlamadoX comparten la misma implementaci�n de x() y setX() esto no es ambig�o?" La respuesta es no. Dentro de un m�todo de ejemplar, el nombre de una variable de ejemplar se refiere a la variable de ejemplar del objeto actual (asumiendo que la variable de ejemplar no est� ocultada por un par�metro del m�todo). Ya que, dentro de x() y setX(), x es equivalente a this.x.

Los objetos externos a UnEnteroLlamadoX que deseen acceder a x deben hacerlo a trav�s de un ejemplar particular de UnEnteroLlamadoX. Supongamos que este c�digo estuviera en otro m�todo del objeto. Crea dos objetos diferentes del tipo UnEnteroLlamadoX, y selecciona sus valores de x a diferente valores y luego lo muestra:

. . .
UnEnteroLlamadoX miX = new UnEnteroLlamadoX();
UnEnteroLlamadoX otroX = new UnEnteroLlamadoX();
miX.setX(1);
otroX.x = 2;
System.out.println("miX.x = " + miX.x());
System.out.println("otroX.x = " + otroX.x());
. . .

Observa que el c�digo utilizado en setX() para seleccionar el valor de x para miX pero s�lo asignando el valor otroX.x directamente. De otra forma, el c�digo manipula dos copias diferentes de x: una contenida en el objeto miX y la otra en el objeto otroX. La salida producida por este c�digo es.

miX.x = 1
otroX.x = 2

mostrando que cada ejemplar de la clase UnEnteroLlamadoX tiene su propia copia de la variable de ejemplar x y que cada x tiene un valor diferente.

Cuando se declara una variable miembro se puede especificar que la variable es una variable de clase en vez de una variable de ejemplar. Similarmente, se puede especificar que un m�todo es un m�todo de clase en vez de un m�todo de ejemplar. El sistema crea una sola copia de una variable de clase la primera vez que encuentra la clase en la que est� definida la variable. Todos los ejemplares de esta clase comparten la misma copia de las variables de clase. Los m�todos de clase s�lo pueden operar con variables de clase -- no pueden acceder a variables de ejemplar definidas en la clase.

Para especificar que una variable miembro es una variable de clase, se utiliza la palabra clave static. Por ejemplo, cambiemos la clase UnEnteroLlamadoX para que su variable x sea ahora una variable de clase.

class UnEnteroLlamadoX {
    static int x;
    public int x() {
        return x;
    }
    public void setX(int newX) {
        x = newX;
    }
}

Ahora veamos el mismo c�digo mostrado anteriormente que crea dos ejemplares de UnEnteroLlamadoX, selecciona sus valores de x, y muestra esta salida diferente.

miX.x = 2
otroX.x = 2

La salida es diferente porque x ahora es una variable de clase por lo que s�lo hay una copia de la variable y es compartida por todos los ejemplares de UnEnteroLlamadoX incluyendo miX y otroX.

Cuando se llama a setX() en cualquier ejemplar, cambia el valor de x para todos los ejemplares de UnEnteroLlamadoX.

Las variables de clase se utilizan para aquellos puntos en los que se necesite una sola copia que debe estar accesible para todos los objetos heredados por la clase en la que la variable fue declarada. Por ejemplo, las variables de clase se utilizan frecuentemente con final para definir constantes (esto es m�s eficiente en el consumo de memoria, ya que las constantes no pueden cambiar y s�lo se necesita una copia).

Similarmente, cuando se declare un m�todo, se puede especificar que el m�todo es un m�todo de clase en vez de un m�todo de ejemplar. Los m�todos de clase s�lo pueden operar con variables de clase y no pueden acceder a las variables de ejemplar definidas en la clase.

Para especificar que un m�todo es un m�todo de clase, se utiliza la palabra clave static en la declaraci�n de m�todo. Cambiemos la clase UnEnteroLlamadoX para que su variable miembro x sea de nuevo una variable de ejemplar, y sus dos m�todos sean ahora m�todos de clase.

class UnEnteroLlamadoX {
    private int x;
    static public int x() {
        return x;
    }
    static public void setX(int newX) {
        x = newX;
    }
}

Cuando se intente compilar esta versi�n de UnEnteroLlamadoX, se obtendr�n errores de compilaci�n.

UnEnteroLlamadoX.java:4: Can't make a static reference to nonstatic variable x in class UnEnteroLlamadoX.
        return x;
               ^
UnEnteroLlamadoX.java:7: Can't make a static reference to nonstatic variable x in class UnEnteroLlamadoX.
        x = newX;
        ^
2 errors

Esto es porque los m�todos de la clase no pueden acceder a variables de ejemplar a menos que el m�todo haya creado un ejemplar de UnEnteroLlamadoX primero y luego acceda a la variable a trav�s de �l.

Construyamos de nuevo UnEnteroLlamadoX para hacer que su variable x sea una variable de clase.

class UnEnteroLlamadoX {
    static private int x;
    static public int x() {
        return x;
    }
    static public void setX(int newX) {
        x = newX;
    }
}

Ahora la clase se compilar� y el c�digo anterior que crea dos ejemplares de UnEnteroLlamadoX, selecciona sus valores x, y muestra en su salida los valores de x.

miX.x = 2
otroX.x = 2

De nuevo, cambiar x a trav�s de miX tambi�n lo cambia para los otros ejemplares de UnEnteroLlamadoX.

Otra diferencia entre miembros del ejemplar y de la clase es que los miembros de la clase son accesibles desde la propia clase. No se necesita ejemplarizar la clase para acceder a los miembros de clase.

Reescribamos el c�digo anterior para acceder a x() y setX() directamente desde la clase UnEnteroLlamadoX.

. . .
UnEnteroLlamadoX.setX(1);
System.out.println("UnEnteroLlamadoX.x = " + UnEnteroLlamadoX.x());
. . .

Observa que ya no se tendr� que crear miX u otroX. Se puede seleccionar x y recuperarlo directamente desde la clase UnEnteroLlamadoX. No se puede hacer esto con miembros del ejemplar. Solo se puede invocar m�todos de ejemplar a trav�s de un objeto y s�lo puede acceder a las variables de ejemplar desde un objeto. Se puede acceder a las variables y m�todos de clase desde un ejemplar de la clase o desde la clase misma.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP