Вы находитесь на странице: 1из 32

MANEJO DE PAQUETES EN JAVA

UTILIZANDO COMO EJEMPLO EL EJERCICIO DE GUERRA FICTICIA

MANEJO DE PAQUETES
Cuando una clase se encuentra dentro de un paquete el nombre de la clase pasa a ser:
"NombrePaquete.NombreClase".

As, la clase "ClasePaquete1" que se encuentra fsicamente en el directorio " paquete1" y cuya primera lnea de cdigo es:
package paquete1;

MANEJO DE PAQUETES
tendr como nombre completo
"paquete1.ClasePaquete1".

Si deseamos, por ejemplo, ejecutar el mtodo main de dicha clase debemos situarnos en el directorio "Paquetes" y teclear el comando:
java paquete1.ClasePaquete1

MANEJO DE PAQUETES
Cuando en una clase no se indica que est en ningn paquete, como hemos hecho hasta ahora en todos los ejemplos, esa clase se sita en el "paquete por defecto (default package). En ese caso, el nombre de la clase es simplemente lo que hemos indicado despus de la palabra reservada class sin precederlo del nombre de ningn paquete. Se puede hacer anidamiento de paquetes.

PROGRAMAS CON PAQUETES


La principal funcionalidad de los paquetes es precisamente ayudar a organizar programas complejos. Vamos a reorganizar el cdigo del ejercicio Guerra Ficticia empleando tres paquetes. Uno de los paquetes lo llamaremos "seres" porque en l ser donde vayan todos los objetos del universo que consideramos "seres". En nuestro caso, irn Marciano, Terrcola, Guerrero y SerVivo. Crearemos un segundo paquete llamado "mquinas donde iran todas las mquinas que implementsemos. En nuestro caso, la nica mquina en el problema es Nave. Por ltimo, creamos un paquete "auxiliar" en la cual colocamos la claseque contiene el mtodo main.

GUERRA FICTICIA CON PAQUETES


Los nicos cambios que ser necesario hacer en el cdigo es incluir las sentencias que indican a qu paquete pertenece cada clase, colocar cada clase en el directorio adecuado y, cuando una clase emplee clases de otros paquetes diferentes al suyo, aadir la sentencia import correspondiente.

GUERRA FICTICIA CON PAQUETES


package seres; //No necesitamos importar nada porque no usamos clases de otros paquetes public abstract class SerVivo { public boolean isVivo(){ return vivo; } . . .

GUERRA FICTICIA CON PAQUETES


package seres; //No necesitamos importar nada porque no usamos clases de otros paquetes public abstract class Guerrero extends SerVivo { public Guerrero (String soy){ blanco = generaBlanco(); this.soy = soy; } . .

GUERRA FICTICIA CON PAQUETES


package seres; //No necesitamos importar nada porque no usamos clases de otros paquetes public class Terricola extends Guerrero { public Terricola(String soy){ super(soy); total++; this.soy= soy; }

GUERRA FICTICIA CON PAQUETES


package seres; //No necesitamos importar nada porque no usamos clases de otros paquetes public class Marciano extends Guerrero { public Marciano(String soy){ super(soy); this.soy =soy; total++; }

GUERRA FICTICIA CON PAQUETES


package maquinas; //necesitamos emplear clases del paquete seres import seres.*; public class Nave { public Nave (String somos){ this.somos = somos; } . . }

GUERRA FICTICIA CON PAQUETES


package auxiliar; //necesitamos emplear la clase Nave import maquinas.*; public class Guerra {

PROBLEMAS CON LOS MODIFICADORES DE ACCESO?


Vamos a realizar un ejemplo donde se implementa el cdigo de visibilidad entre los paquetes utilizando los modificadores de acceso:

Crear un proyecto nuevo. El proyecto va a contener dos paquetes: Paquete 1 y Paquete 2 . El paquete 1 va a contener:
ClasePaquete1 ClasePaquete1Herencia

EJEMPLO
La clase "ClasePaquete1" emplear a una clase del segundo paquete (crear a una instancia de ella e invocar mtodos) y la clase "ClasePaquete1Herencia" heredar de una clase del otro paquete. El contenido del segundo paquete es:
ClasePaquete2, que usa a ClasePaquete2Privada

La clase accesible desde fuera del paquete emplea a la clase no accesible desde fuera.

EJEMPLO
Esa clase es "un detalle de implementacin" de este paquete. Si en el futuro la modificamos, la eliminamos, creamos ms clases para repartir sus responsabilidades... ningn cdigo que emplee "paquete2" se dar cuenta de dichos cambios ya que nunca conoci la existencia de esa clase. Veamos ahora el cdigo de cada una de las clases:

EJEMPLO
package paquete2; //esta clase tiene visibilidad de paquete, formar parte //de los detalles de implementacin de este paquete. class ClasePaquete2Privada { void visibilidadPublica() { System.out.println("Mensaje del mtodo con visibilidad pblica de la clase con visibilidad de paquete"); }

EJEMPLO
void visibilidadPaquete(){ System.out.println("Mensaje del mtodo con visibilidad de paquete de la clase con visibilidad de paquete"); } protected void visibilidadProtegida(){ System.out.println("Mensaje del mtodo con visibilidad protegida de la clase con visibilidad de paquete"); } private void visibilidadPrivada (){ System.out.println("Mensaje del mtodo privado de la clase con visibilidad de paquete"); } }

EJEMPLO
package paquete2; /*Esta clase es pblica, por lo tanto formar parte de la interfaz del paquete*/ public class ClasePaquete2 { public void saludar() { System.out.println("Hola"); //por supuesto, la clase puede acceder a sus mtodos //privados this.privado(); //protegidos this.visibilidadProtegida(); //y de paquete this.visibilidadPaquete();

EJEMPLO
//aqu usamos los "detalles de implementacin" del paquete ClasePaquete2Privada objeto2 = new ClasePaquete2Privada(); //por supuesto, pueda acceder a su parte pblica //objeto2.visibilidadPublica(); //y, como estoy en el mismo paquete, a la parte //con visibilidad de paquete objeto2.visibilidadPaquete (); //tambin a la parte protegida porque estamos en //el mismo paquete objeto2.visibilidadProtegida (); //pero no la privada // objeto2.visibilidadPrivada (); }

EJEMPLO
void visibilidadPaquete(){ System.out.println("Mensaje del mtodo con visibilidad de paquete"); } protected void visibilidadProtegida(){ System.out.println("Mensaje del mtodo con visibilidad protegida"); } private void privado (){ System.out.println("Mensaje del mtodo privado"); }

EJEMPLO
El contenido de "paquete1, donde sus clases tienen mtodos main y, por tanto, se pueden ejecutar. Las dos clases de este paquete emplean la clase pblica del paquete anterior, o bien porque crea un objeto de ella o bien porque heredan de ella.
package paquete1; //para poder usar la clase del otro paquete import paquete2.*;

EJEMPLO
public class ClasePaquete1 { public static void main (String[] args){ //accedemos a la clase pblica del otro paquete ClasePaquete2 objeto = new ClasePaquete2(); //si quitas el comentario de esta lnea obtendrs un error al compilar //esta clase tena visibilidad de paquete y no puede ser cedida //desde aqu // ClasePrivadaPaquete2 objeto = new ClasePrivadaPaquete2(); //por supuesto, se siguen cumpliendo las normas de siempre //para el acceso a las partes pblicas, privadas, protegidas y con //visibilidad de paquete

EJEMPLO
objeto.saludar(); //no puedo acceder al mtodo privado: // objeto.privado (); //ni al que tiene visibilidad de paquete // objeto.visibilidadPaquete (); //ni, por supuesto, al privado // objeto.visibilidadPrivada() } }

EJEMPLO
package paquete1; import paquete2.*; //la clase hereda de ClasePaquete2, por tanto va a //poder acceder a sus partes protegidas y con //visibilidad de paquete //adems de, por supuesto, a la parte pblica public class ClasePaquete1Herencia extends ClasePaquete2 { public static void main (String[] args){

EJEMPLO
//creamos una instancia de esta clase. No la hemos dotado de //ningn mtodo, pero podremos acceder a los mtodos que //hemos heredado de ClasePaquete2 ClasePaquete1Herencia objeto = new ClasePaquete1Herencia(); //no puedo acceder al mtodo privado: // objeto.visibilidadPrivada() //ni al que tiene visibilidad de paquete // objeto.visibilidadPaquete(); //pero si al protegido objeto.visibilidadProtegida(); objeto.saludar(); } }

EJEMPLO
La salida que produce la ejecucin del mtodo main de "ClasePaquete1" es:

EJEMPLO
y la que produce el mtodo ClasePaquete1Herencia" ser: main de "

MEJORAS DEL PROGRAMA DE GUERRA FICTICIA


La primera mejora que se le puede hacer al cdigo de la batalla entre marcianos y terrcolas tiene que ver con la herencia: en la clase Guerrero hay una variable privada de tipo cadena de caracteres que se llama soy. Esta variable contena la cadena de caracteres Marciano o Terrcola segn el guerrero fuese un Marciano o un Terrcola.

Tanto la clase Marciano como Terrcola poseen otra variable privada llamada soy que almacena la misma cadena de caracteres.

MEJORAS DEL PROGRAMA DE GUERRA FICTICIA


Las dos clases emplean esa cadena de caracteres para imprimir sentencias por la consola; la clase Guerrero para imprimir el texto soy + Dispara n + disparo, y las clases hijas para imprimir soy + Muerto por disparo n + i. Por cada objeto Marciano o Terrcola que creemos se van a almacenar dos cadenas de caracteres con el texto Marciano, y Terrcola respectivamente, ya que las clases hijas no van a poder acceder a la clase privada de la superclase.

Esto se puede resolver simplemente haciendo protegida (protected) la variable soy en Guerrero, de tal modo que Terrcola y Marciano la hereden.

MEJORAS DEL PROGRAMA DE GUERRA FICTICIA


La segunda mejora tiene que ver con las lneas return ((Terricola)(tripulacion[1])).getTotal(); y return ((Marciano)(tripulacion[1])).getTotal();.

El propsito de estas sentencias era averiguar el valor de las variables estticas total definidas en Terrcola y Marciano respectivamente, variables que nos permitan llevar cuenta de cuantos marcianos y terrcola haba vivos en cada momento.

MEJORAS DEL PROGRAMA DE GUERRA FICTICIA


El resultado sera el mismo si lo invocsemos sobre otro tripulante, todos los mtodos getTotal() de todos los tripulantes devuelven el mimo dato, la variable esttica total. Cuando un mtodo slo accede a variables estticas, como es el caso de getTotal(), lo ms lgico es que el mtodo tambin sea esttico, ya que si slo accede a informacin de la clase y no de una de las instancias lo lgico es preguntarle a la clase y no a una de las instancias por el.

MEJORAS DEL PROGRAMA DE GUERRA FICTICIA


Definiendo este mtodo como esttico (static) es Terrcola y Marciano podramos haber cambiado las lneas return ((Terricola)(tripulacion[1])).getTotal(); y return ((Marciano)(tripulacion[1])).getTotal(); por return Terricola.getTotal(); y return Marciano.getTotal();, quedando el cdigo mucho ms claro.

Вам также может понравиться