lunes, 27 de julio de 2009

SCJP Declaraciones Inicializacion y Alcance 3

Declarando miembros de clase
Como vimos una clase puede tener solo 2(default y public) de los 4 modificadores de acceso que los miembros(métodos y variables de instancia) pueden usar: public, protected, default y private.
La protección por default que obtenemos es aquella cuando no escribimos el modificador de acceso en la declaración del miembro como:

public class Algo{
-- Si no escribimos el modificador de acceso a este miembro de
-- clase entonces asume el por default
int x;

-- Este miembro de clase declara explicitamente el tipo de
-- protección a private
private int y;
}

Los controles de acceso default y protected tienen exactamente el mismo comportamiento excepto por una diferencia: el miembro con control de acceso default puede ser accedido solo si la clase accediendo al miembro pertenece a el mismo paquete, a diferencia un miembro con control de acceso protected puede ser accedido(a través de herencia) por una subclase, incluso si la subclase está en un paquete diferente. Veamos algo de código para clarificar la teoria:

package miempresa.core;

public class ClaseA{

-- Si no especificamos el control de acceso a este
-- método entonces se le asigna default
int sumarA(int x,int y){
return (x+y);
}

-- Aqui le asignamos el control de acceso
--explicitamente a protected
protected int restarA(int x,int y){
return (x-y);
}
}


Ahora veamos otra clase que está en otro paquete y que referencia a la clase anterior:

package miempresa.util;
import miempresa.core.ClaseA;

-- La extensión de la ClaseA la podemos realizar ya que su
-- modificador es public
public class ClaseB extends ClaseA{

int sumarB(int x,int y){
-- Lo siguiente es incorrecto ya que sumarA tiene acceso por default
-- y está tratando de ser accedido por la ClaseB que se
-- encuentra en otro paquete
return sumarA(x,y);
}

-- Aqui le asignamos el control de acceso explicitamente a protected
-- Si se compilara solo esta parte entonces todo estaría OK. porque
-- el control de acceso de restarA es protected
protected int restarB(int x,int y){
return restarA(x,y);
}
}

Miembros públicos
Cuando un método o variable miembro es declarado público public significa que todas las otras clases(incluso las que no están en el mismo paquete) pueden acceder al miembro ( asumiendo que la clase es visible )

Miembros privados
Miembros marcados private no pueden ser accedidos por código en cualquier otra clase más que la propia clase en la cual el miembro private fué declarado.

Miembros protected
Veamos un ejemplo:

package miempresa.core;
public class ClaseA{
protected double sueldo;
}


El código anterior declara una variable sueldo como protegida protected. Esto hace la variable accesible a todas las otras clases dentro del paquete miempresa.core así como tambien heredable por cualquier subclase fuera del paquete miempresa.core. Ahora crearemos una subclase en un paquete diferente e intentaremos usar la variable sueldo.

package miempresa.rrhh;
import miempresa.core.ClaseA;
public class ClaseB extends ClaseA{
public void procesar(){
sueldo = 3000;
-- Como vemos heredamos la variable sueldo sin problemas
System.out.println("Mi sueldo fue:"+sueldo);
}
}

El código anterior compila bien, debemos notar que la subclase accede a la variable protegida a través de herencia extends. Pero que pasa si queremos acceder a la variable sueldo sin usar herencia, es decir, usando una instancia de la clase ClaseA, veamos:

package miempresa.rrhh;
import miempresa.core.ClaseA;
public class ClaseB extends ClaseA{
public void procesar(){
sueldo = 3000;
-- Como vemos heredamos la variable sueldo sin problemas
System.out.println("Mi sueldo fue:"+sueldo);

-- Ahora veamos que pasa si instanciamos
-- una clase y tratamos de acceder a la variable protegida
ClaseA claseA = new ClaseA();
-- Lo siguiente nos dará un error de compilación
-- porque la variable es protegida y solo es accesible a través
-- de herencia
System.out.println("Mi sueldo fue:"+claseA.sueldo);
}
}


Variables locales y modificadores de acceso.
Podemos aplicar los modificadores de acceso(public,protected,private) a las variables locales?, es decir el siguiente código es válido?:

public class ClaseA{
public void procesar(){
-- Variable local con modificador de acceso:
private int suma;
}
}

Pues claro que no, no tiene sentido colocar un modificador de acceso a una variable local, esa variable fué declarada solo para ser usada en el ámbito que le corresponde, en el ejemplo el ambito es el método procesar(). Como vemos ningún modificador de acceso puede ser asignado a una variable local, a una variable local solo le podemos asignar un modificador de no-acceso el cual es final, lo cual indica que solo es de lectura(no podemos asignarle un valor).

Métodos finales
La palabra clave final protege a un método de ser sobreescrito en una subclase, veamos un ejemplo, si nosotros tenemos una clase llamada UtilFechas que tiene un método fechaActual, de la siguiente manera:

public class UtilFechas{
public final String fechaActual(){
return "la fecha actual";
}
}

y alguien por allí trata de extender la clase anterior y trata de sobreescribir el método de la siguiente manera:

public class UtilFechasExtendido extends UtilFechas{
-- Esto trata de sobreescribir el método de UtilFechas
public String fechaActual(){
return "la fecha actual de UtilFechasExtendido";
}
}

Entonces el compilador observará que la clase UtilFechas ha marcado su método fechaActual como final (no podemos sobreescribirla) pero la clase UtilFechasExtendido trata de sobreescribirlo, por lo tanto al momento de compilar retornará un error al usuario.

Argumentos Finales
Los argumentos de los métodos son las declaraciones de variables que aparecen entre los parentesis en una declaración de un método, una declaración común de un método con varios argumentos luce así:

public int sumar(int x, int y, int z){
return (x+y+z);
}

El método anterior tiene tres argumentos int x, int y, int z

Los argumentos de los métodos son igual que las variables locales, esto significa que pueden tener el modificador final

public int sumar(int x, final int y, final int z){
return (x+y+z);
}

En el ejemplo anterior los argumentos int y, int z son marcados con el modificador final, lo cuál significa que sus valores no pueden ser cambiados, es decir no pueden asignarseles otro valor(no podemos hacer y = 78; ó z = 100; ) por lo que estos argumentos mantienen su valor como el parametro que fué usado al momento de llamar al método. Es decir si tenemos en otro metodo una llamada al método sumar de la siguiente manera:

int p1 = 10;
int p2 = 20;
int p3 = 30;
int suma = sumar(p1, p2, p3);

Entonces los parametros p2 y p3 se mantendrán inmutables(no cambia su valor) durante la ejecución del método.




No hay comentarios.:

Publicar un comentario

Es bueno comunicarnos, comenta!!.