Introducción a la Programación Orientada a Objetos (POO)
APARTADOS
* Programación lineal * Programación modular * Programación estructurada * Programación orientada a objetos |
La POO es una técnica de programación que usa los objetos como bloque esencial de construcción.
Inicialmente si se quería almacenar
información, por ejemplo de la entidad “cliente” existían
una serie de datos “aislados”: nombre, domicilio, localidad,
fecha última compra. Por tanto para hacer una factura todos estos
elementos eran procesados de forma individual. |
Abstracción
Un primer intento de construir tipos de datos más complejos, que se parecieran a las situaciones del mundo real y que pudieran ser tratados (más o menos) como una unidad, lo constituyen, entre otros, las "estructuras" del C clásico ("registros" en otros lenguajes). |
En esta etapa ya podía crearse
una estructura "cliente" que albergara toda la información
antes dispersa. Pero las herramientas para manipularlos seguían
siendo elementos totalmente diferenciados. |
Abstracción
Las clases son conjuntos de datos definidos por el programador, parecidos a las mencionadas "estructuras", pero con la importante novedad de incluir también las herramientas necesarias para su manipulación: operadores y funciones de la programación tradicional. |
Un TAD es un tipo de dato en el
cual existe un conjunto de operaciones las cuales se pueden aplicar a ellos
mismos. Un objeto también va a ser una colección de datos con
operaciones asociadas pero tendrá una serie de propiedades que le dotan
de una gran potencia:
Herencia
Encapsulación
Polimorfismo
Un objeto estará formado
por datos y funciones ( a éstos se les llama miembros ). Tanto los datos
como las funciones se “encapsulan” y solamente serán accesibles
mediante las funciones miembro.
Las funciones miembro son también conocidas como “métodos”.
Las clases serán plantillas o modelos
que describen objetos de un mismo tipo.
Para crear un objeto se tiene que instanciar una clase.
Un mensaje es la petición de un objeto
a otro para que ejecute uno de sus métodos.
Un mensaje tiene tres partes:
Identidad objeto receptor
Método que se quiere ejecutar
Parámetros que necesite el objeto receptor para ejecutar dicho método
El principio de la herencia es que cada subclase comparta características de la clase de la cual se deriva.
Cada subclase tendrá sus propias características particulares.
NOTA IMPORTANTE: La herencia permite “reutilización de código” pues deja definir nuevas clases a partir de clases ya existentes
Una misma operación puede tener distintos comportamientos según el objeto del que se trate ( polimorfismo )
Por ejemplo el operador “+” tendrá distinto significado si tenemos operadores de tipo numérico que si tenemos operadores de tipo cadena (concatenación)
Cada objeto (instancia de una clase) tendrá sus propias variables pero compartirá sus métodos con el resto de los objetos de la misma clase.
Por ejemplo, un punto en el plano tendrá sus propias coordenadas y una serie de operaciones que se pueden realizar sobre él
Para poder representar las clases independientemente del lenguaje utilizado se usa UML (Unified Model Language-Lenguaje Unificado de Modelado). Las clases se representan mediante cajas: parte superior "nombre clase", parte intermedia "propiedades" y parte inferior "métodos". Tanto las propiedades como los métodos podrán ser públicos (+), privados (-) y protegidos (#):
Punto |
- x: double - y : double |
+ Punto() + Punto(double, double) + trasladar (double, double) + distancia(Punto): double + abscisa(): double + ordenada(): double |
Tanto los métodos, como las propiedades y las clases, tendrán la siguiente visibilidad:
NOTA: No asustarse, no tenéis que memorizar la tabla, podéis usarla cada vez que os haga falta consultando esta documentación.
JVM, JDK, JRE
Sun Microsystems elabora un lenguaje de programación para su uso en electrodomésticos (año 1991).
Java puede usarse, fundamentalmente, en los siguientes tipos de proyectos:
* Stand-alone Application. Aplicación independiente
* Applet. Aplicación ejecutada en el navegador. Primero se descarga la aplicación y luego es ejecutada en la máquina cliente.
* Servlet. Aplicación que se ejecuta en el servidor (no suele tener interfaz gráfica). Generalmente se desarrollan aplicaciones en las cuales se comunica el servlet con el applet.
Para el desarrollo de programas se usa el JDK(Java Development Kit o también conocido como SE - Standard Edition). Si solamente queremos "ejecutar" código en Java hará falta únicamente el JRE(Java Runtime Environment).
El intérprete de Java es el JVM(Java Virtual Machine). El JVM "interpreta" el byte code(código intermedio: código menos abstracto, más compacto y más orientado a la máquina ) transformándolo al código de la CPU usada.
Por tanto habrá que realizar dos pasos:
1) Compilar programas para convertilos en bytecode. (javac ejemplo.java)
2) Ejecutarlo mediante un intérprete de bytecode. (java ejemplo)
Para poder llamar a java.exe o a javac.exe se tendrá que conocer la ruta. Por tanto habrá que especificarla en la variable de entorno PATH (set PATH=.;c:\jdk1.2\bin;%PATH%).
¿Cómo sabe dónde se encuentran las librerías o las clases?. Para ello habrá que especificarlo en la variable de entorno CLASSPATH (set CLASSPATH=.\;c:\jdk1.2\lib\classes.zip;%CLASSPATH%). El punto que hay después del igual es imprescindible escribirlo pues es la forma de indicar que busque también en el directorio actual.
Existe la posibilidad de especificar la carpeta donde se encuentran las librerías en el comando de ejecución. Ejemplo:
java -classpath .\;c:\proyecto\misClases.jar programaCreado (también se puede usar -cp para no tener que escribir la palabra -classpath)
En el ejemplo anterior podéis observar un archivo con extensión .jar. Este tipo de archivos se usa para comprimir en un único archivo un cierto contenido para su posterior distribución y uso. Para ejecutar un archivo .jar se escribe la siguiente sentencia: java -jar archivo.jar.
Las variables de entorno en Windows XP se configuran en: Propiedades del sistema>>Solapa Opciones Avanzadas>>Variables de Entorno.
Si tienes propiedades con el propio intérprete de Java tendrás que dirigirte al registro de windows (regedit): MI PC>>HKEY_LOCAL_MACHINE>>SOFTWARE>>JavaSoft>>Java RunTime Environment. En esa clave tendrás que modificar el valor de "CurrentVersion" (algunas ves se tendrá que cambiar la versión, por ejemplo algunas aplicaciones solamente funcionan con versiones concretas como la 1.6...)
EJERCICIO:
1) Bájate la última versión JDK también conocida como SE (Standard Edition)
2) Comprueba que está bien configurada. Ir a la interfaz de comandos (INICIO>EJECUTAR>"cmd") y escribir el comando "java -version". Si no aparece la versión, configura las variables de entorno tal y como se explica justo en este apartado
3) Bájate la API de Java buscándola en la página de Sun o con un motor de búsqueda(Java™ Platform, API Specification). Descomprímela en una carpeta y añade en favoritos el archivo "index.html" de dicha carpeta.
Nuestro primer programa en Java
Descargue el JDK y haga los cambios en las variables de entorno tal y como se dijo en el apartado anterior.
Crea un archivo con un editor de texto puro y llámalo "PrimerProgramaJava". Copia el siguiente contenido:
//***************************************************************************************************************
//Así se escribe un comentario en Java para una única
línea /*Comentarios de más de una línea*/ class PrimerProgramaJava //==>DECLARACIÓN DE CONSTANTES |
||
//==>FUNCIÓN PRINCIPAL.
Toma como parámetro los argumentos enviados al programa(array de
tipo String) //==>CLASE "String". //Se pueden declarar variables String de dos formas: //1)String cadena1= "Hola a todos"; //2)String cadena2 = new String("Hola a todos"); public static void main(String args[]) { |
||
//Se crea una referencia a la clase mediante la variable "primero". Porque aunque el main esté dentro de la clase si queremos //usar las propiedas y/o métodos de la clase tendremos que crear una instancia de la misma. PrimerProgramaJava primero; //Se instancia la clase(se crea el objeto). Por tanto se llamará
al constructor //==>El operador "+"
en cadenas servirá para la concatenación //Se está accediendo a la propiedad "saludo" |
||
} | ||
} |
//***************************************************************************************************************
En la línea de comandos primero tendrás que crear el archivo bytecode:
javac PrimerProgramaJava.java
Una vez generado el archivo .class ahora podrás ejecutarlo:
java PrimerProgramaJava
NOTA: Lee el código fuente del programa anterior
EJERCICIO: Usando una IDE de Java (Eclipse, NetBeans, JBuilder, etc...) crear el proyecto "proyectoPunto" y codifica el siguiente código:
c l a s s Punto {
/ / Coordenadas punto
pr ivate double x , y ;
/ /Incrementa coordenadas del puntro
public void t r a s l ada r ( double a , double b ){x = x + a ;
y = y + b ;}
/ / Devuelve la distancia entre este punto y el argumento
public double di s t anc i a ( Punto pto ) {return Math . sqr t (Math .pow( x - pto . x , 2) + Math .pow( y - pto . y , 2) ) ;
}
/ / Devuelve coordenada x
public double abs c i s a ( ) { return x ;
}
/ / Devuelve coordenada y
public double ordenada ( ) { return y ;
}
/ / Cambia valor de abscisa
public void abs c i s a ( double nuevaX) { x = nuevaX ;
}
/ / Cambia valor de ordenada
public void ordenada ( double nuevaY) { y = nuevaY ;
}
}
EJERCICIO: Crea el procedimiento main para probar el funcionamiento de la clase (public static void main(String args[]))
Los arrays en Java son arrays de objetos. Para crear un array habrá que usar el operador "new" seguido del tipo y el número de elementos:
double []datos; //Se crea una referencia. Se podría poner también double x[];
datos= new double[200]; //Se crea el array
//Las dos instrucciones anteriores se podrían haber realizado en una sola: double []datos = new double[200];
//Otras formas de inicializar los arrays
String diasSemana[] = {"lunes", "martes", "miercoles", "jueves", "viernes", "sabado", "domingo"};
//Si se ejecuta "diasSemana.length" devolverá el número de elementos de la tabla
//Arrays de objetos:
MiClase objetos[]= new MiClase[10]; /
for (i=0;i<10;i++)
objetos[i] = new MiClase();
//MATRICES
double [][]datos;
datos = new double[numero_filas][];
for(i=0;i<numero_filas;i++)
datos[i] = new double[numero_columnas];
//También se puede crear una matríz de la siguiente manera
float datosSalario = new float[4][3];
//Forma de inicializar la matriz
int [][]datosEnterosMatriz = { {0,1,2},
{3,4,5}};
EJERCICIO: Imprimir en pantalla el nombre de los doce meses que conforman un año. (Pista: Puedes ver en los ejemplos de arriba cómo se ha declarado la variable "diasSemana"). Para saber cuántos elementos tiene el array será obligatorio el uso de "length".
EJERCICIO: Crear el proyecto "sumaNumero". Este proyecto tendrá la clase "suma.java". Esta clase mostará en pantalla la suma de 20 números, estos números serán números seleccionados al hazar.
NOTA PARA HACER EL EJERCICIO:
1) Habrá que importar la clase Random (import java . u t i l .Random;)
2) Se creará un objeto de la clase Random (Random rnd = new Random( ) )
3) Para generar un número aleatorio, por ejemplo del tipo double, se haría de la siguiente manera: rnd . nextDouble ( ) ; Queda como ejercicio que el programador busque en la API de Java qué método devuelve un valor entero.
Los tipos primitivos (float, char, double, long, byte, short, etc...) se pasan por "valor" a los procedimientos, sin embargo los objetos se pasan por referencia. Por tanto no se podrían modificar las variables que pertenezcan a un dato primitivo, y una solución para ello es usar los "Wrappers" (envoltorios).
Para cada tipo primitivo existe un Wrapper: Float, Double, Long, Integer, Byte, etc...
Ejemplo:
Integer num = new Integer(17);
Por tanto Java hace distinción entre tipos primitivos y clases. Supongamos el caso de disponer de una lista que sea capaz de almacenar objetos y nosotros poseemos una tabla de enteros -> SOLUCIÓN: Convertir estos tipos primitivos en sus envoltorios correspondientes, este proceso sería la encapsulación. Ejemplo:
Integer [ ] l i = new Integer [ 3 ]
;
l i [ 0 ] = new Integer ( 4 ) ;
l i [ 1 ] = new Integer ( ” 87 ” ) ;
l i [ 2 ] = new Integer (22) ;
Lo que ocurre es que Java es capaz de hacer la conversión sin indicarlo de forma explícita. Ejemplo:
Integer [ ] l i = new Integer [ 3 ]
;
l i [ 0 ] = 4;
l i [ 1 ] = Integer . par seInt ( ” 87 ” ) ;
l i [ 2 ] = 22;
EJERCICIO: Dado un array de 5 números ordenarlos mediante el método de la burbuja.
NOTA: Los 5 números no serán introducidos por el usuario sino que vendrán ya definidos en el propio código
Salida estándar
System.out.println("Buenas tardes");
"println" es un método de visualización. Soporta como parámetro una cadena, un carácter, etc...
(void println(char x), void println(char[] x),void println(double x),void println(float x),void println(int x),void println(long x),
void println(String x),...)
"out" es una variable estática y "System" es una clase (esta clase pertenece al package por defecton"java.lang")
Entrada estándar
Para la entrada estándar se podría usar el objeto "in". Ejemplo:
int c;
c=System.in.read();
Usar el objeto "in" sería bastante pesado pues se tendría que recuperar carácter por carácter. Para solucionar esto se podría redireccionar la entrada de tal forma que se capture líneas (secuencia de caracteres hasta pulsar la tecla ENTER). Para ello primero habrá que importar el package "io" y seguir los siguientes pasos:
import java.io.*;
//Primer paso. Se redirecciona la entrada.
InputStreamReader entrada = new InputStreamReader(Sytem.in);
//Segundo paso. Crear un buffer de entrada para la entrada redireccionada en la sentencia anterior
BufferedReader bufferEntrada = new BufferedReader(entrada);
//Lógicamente se podría haber creado en una única línea:
//BuffedReader bufferEntrada = new BufferedReader(new InputStreamReader(System.in));
//YA SE PUEDE USAR LA ENTRADA Y EL BUFFER CREADO
//Para capturar una línea escribir la siguiente sentencia
String cadena = bufferEntrada.readLine();
El código de arriba funciona perfectamente. Pero, ¿qué ocurre si lo que queremos es capturar un entero?. La respuesta es muy sencilla se captura una cadena y luego se convierta a tipo entero:
int numero = Integer.parseInt(cadena);
EJERCICIO: Crea la clase "capturaEntrada" según la especificación del siguiente diagrama:
capturaEntrada |
- cadenaCaptura: String |
+ capturaLinea():String + capturaEnteroPrimitivo():int + capturaEnteroLargoPrimitivo():long + capturaRealPrimitivo(): float + capturaDoblePrimitivo(): double + capturaBooleanPrimitivo():boolean + capturaEntero():Integer + capturaEnteroLargo():Long + capturaReal():Float + capturaDoble(): Double + capturaBooleanPrimitivo():Boolean |
Todos devolverán el tipo de dato indicado.
La comprobación de errores se hará en un ejercicio posterior (es decir, que se solicite al usuario un entero y él introduzca por ejemplo un número decimal)
Los programas pueden producir errores en tiempo de ejecución. Ejemplos: un fichero que no existe, un índice fuera de rango, etc...
Dentro de "try" irían las instrucciones que pueden provocar excepciones, en los bloques "catch" irían los manejadores de excepciones.
"finally" es opcional, y su función es la de dejar el programa en un estado correcto independientemente de lo que suceda dentro del bloque try (cerrar ficheros, liberar recursos, ...). Siempre se ejecuta
PrintWriter out = null;
try {
out = new PrintWriter(new FileWriter(“out.txt”));
for (int i = 0; i < SIZE; i++) {
out.println(“valor: ” + i + “ = ” + v[i]);}
}catch (ArrayIndexOutOfBoundsException e) {
System.err.println(“Índice fuera de rango”);
}
catch (IOException e) {
System.err.println(“out.txt no pude abrirse");
}finally {
if (out != null) {
out.close();
}
}
}
A veces, es mejor no tratar la excepción y dejar que el método superior que haya invocado a dicho método sea el que los trate ( pila de llamadas):
public void escribeLista() throws IOException, ArrayIndexOutOfBoundsException
Se puede provocar una excepción con la instrucción "throw":
public void pop() throws EmptyStackException {
if (size == 0) {
throw new EmptyStackException();
}
Ejemplo de uso de control de excepciones:
public void insertar(int pos, T elem) {
// Se comprueba que la posición "pos" está dentro del rango permitido
if ((pos < 0) || (pos > tamaño)) {
throw new RuntimeException("Índice fuera de rango");
}else {
if (tamaño >= lista.length) {
//Si lista esta llena se duplica su tamaño
T[] listaNueva = (T[]) new Object[2 * lista.length];
for (int i = 0; i < tamaño; i++) {
listaNueva[i] = lista[i];
}
lista = listaNueva;
}
// Ya se puede hacer la inserción...
for (int i = (tamaño - 1); i >= pos; i--) {
lista[i + 1] = lista[i];}
lista[pos] = elem;
tamaño++;
}
}
EJERCICIO: Modifica la clase "capturaEntrada" para que detecte (mediante control de excepciones) entradas no válidas. Ejemplo: se solicita al usuario un entero y escribe un número decimal. Observar el ejemplo anterior para poder realizar este ejercicio
Los constructores indican cómo crear objetos estableciendo sus valores iniciales. El nombre de los constructores tiene que coincidir con el nombre de la clase.
c l a s s Punto {
/ / Constructor para inicializar ambas coordenadas a cero
public Punto ( ) { x = y = 0 ; }
/ / Constructor que inicializa las dos coordenadas a los valores dados
Punto ( double a , double b ) { x = a ; y = b ; }
....................
}
EJERCICIO: Al proyecto "proyectoPunto" añadir los dos constructores definidos en el apartado anterior. Verificar su funcionamiento
EJERCICIO: Comprobar y entender el funcionamiento del siguiente código (llamarlo "cPersona.java"):
//***************************************************************************************************************
//Descripción: Implementación de la clase
cPersona. Esta clase almacena las propiedades: apellidos, nombre, //Autor: Daniel Leyva Cortés import java.io.*; //Para poder recuperar datos de la "entrada" estándar habrá que importar el paquete "io" class cPersona |
|||
//Declaración de propiedades de la clase: private String apellidos; private String nombre; private int edad; private long dni; private boolean rellenado; //==>DECLARACIÓN DE CONSTANTES |
|||
apellidos= new String(""); nombre = new String(""); edad=0; dni = 0; rellenado=false; |
|||
} //Método para visualizar las propiedades de la clase public void visualiza() { |
|||
if(!rellenado) { |
|||
System.out.println("No se ha inicializado ningún valor"); | |||
} else { |
|||
System.out.println("*******************************************"); System.out.println("Nombre: " + nombre); System.out.println("Apellidos: " + apellidos); System.out.println("Edad: " + edad); System.out.println("DNI: " + dni); System.out.println("*******************************************"); |
|||
} | |||
} //Métodos para agregar valores en los campos public void setApellidos(String apellidos) { //IMPORTANTE: Esta sentencia en C++ sería "this->" pues era un puntero a un objeto, pero en Java //es directamente un objeto |
|||
this.apellidos = new String(apellidos); rellenado= true; |
|||
}
//Métodos para
agregar valores a los campos |
|||
this.edad = edad; rellenado= true; |
|||
}
//Métodos para
agregar valores a los campos |
|||
this.dni = dni; rellenado=true; |
|||
}
public void setNombre(String nombre) |
|||
this.nombre = new String(nombre); rellenado=true; |
|||
}
//Programa principal.
En este ejemplo lo usaremos únicamente para comprobar que |
|||
cPersona persona; String apellidosLocal; String nombreLocal; int edadLocal; long dniLocal; //Para capturar datos de la entrada estándar cEntrada entrada = new cEntrada(); //Se instancia la clase(se crea el objeto).
Por tanto se llamará al constructor System.out.println("************************************"); System.out.print("Nombre: "); persona.visualiza(); |
|||
} | |||
class cEntrada { //Variables para la entrada y el buffer respectivamente InputStreamReader entrada; BufferedReader bufferEntrada; |
|||
public cEntrada() { |
|||
//Primer paso. Se redirecciona
la entrada. entrada = new InputStreamReader(System.in); //Segundo
paso. Crear un buffer de entrada para la entrada redireccionada en la
sentencia anterior //YA SE PUEDE USAR LA ENTRADA Y EL BUFFER CREADO |
|||
} public String leeCadena() { |
|||
String cadena = new String("");
//Inicializamos
la cadena con valor cadena vacía pues si no se puede ejecutar el
bloque try try |
|||
//Se recupera cadena cadena = bufferEntrada.readLine(); |
|||
catch(java.io.IOException excepcionProducida ) //Podría incluirse opcionalmente,
en el tratamiento de las excepciones, el siguiente bloque //Se devuelve cadena recuperada |
|||
} | |||
} |
//***************************************************************************************************************
Una vez analizado el código se podrá comprobar que conviven dos clases en el mismo archivo: cPersona y cEntrada. La clase principal tendrá que llevar el mismo nombre que el archivo al cual pertenece (esta clase será la que tendrá el procedimiento main definido)
Liberar recursos y destructores
El propio sistema se encargará de liberar de forma automática los objetos de los cuales se haya perdido referencia. Este sistema se denomina "Garbage collection".
Para llamar de forma explícita al recogedor de basura se escribirá la siguiente sentencia:
System.gc();
Existe un método especial denominado "finalize()". En este método se suelen cerrar ficheros, conexiones de red, etc... Este método sería el destructor de la clase
El garbage collector libera memoria reservada con el operador "new", pero si se usa "malloc y free" se tendrián que escribir las sentencias necesarias para liberar memoria.
El finalizador tendrá que llamar al finalizador de la superclase.
Los paquetes permiten almacenar y organizar archivos java, pues éstos actuan como contenedores de clases.
Para que una clase forme parte de un paquete (package) habrá que indicarlo de forma explícita en la primera línea de código (sin contar las líneas de comentarios):
package nombrePaquete;
Los paquetes hacen referencia a archivos bytecode (*.class)
Si se usa la sentencia "import nombrePaquete" se consigue abreviar los nombre de clases, variables y métodos cada vez que se use, sin tener que escribir el nombre del paquete.
Generalmente se nombran las clases con denominaciones únicas en internet, y para conseguirlo se usa el nombre del dominio. Ejemplo:
import es.almudeyne.infor2.ordenar.*; //Estas clases deberían estar en el directorio: classpath \es\almudeyne\infor2\ordenar
Hay un paquete que es importado automáticamente por el JDK y es el paquete java.lang. Por tanto no habrá que importarlo de forma explícita.
A continuación se verá un ejemplo en el cual estará organizado de la siguiente manera:
1) En la carpeta "d:\java\PaqueteEjemplo\Paquete" estarán ubicados los archivos "cCirculo.java" y "cEntrada.java". Estos dos archivos constituyen la implementación del paquete
2) En la carpeta "d:\java\PaqueteEjemplo\" estará situado el archivo "usaPaquete.java". La finalidad de este archivo es el uso del paquete creado.
//************************************ cCirculo.java ****************************************
//Descripción: Ejemplo de paquete en Java //Autor: Daniel Leyva Cortés, Contacto: transistor47@hotmail.com package Paquete; public class cCirculo |
||
private double radio; private final double PI= 3.1416;
|
||
this.radio = radio; | ||
}
public double superficie() |
||
return(PI*radio*radio); | ||
} | ||
} |
//************************************ cEntrada.java ****************************************
public class cEntrada { InputStreamReader entrada; BufferedReader bufferEntrada; |
|||
public cEntrada() { |
|||
entrada = new InputStreamReader(System.in); bufferEntrada = new BufferedReader(entrada); |
|||
public String leeCadena() { |
|||
String cadena = new String("");
try |
|||
cadena = bufferEntrada.readLine(); | |||
} catch(java.io.IOException excepcionProducida ) { |
|||
System.err.println("Problema al intertar leer de la entrada estándar..."); | |||
} return new String(cadena); |
|||
} | |||
} |
Para compilarlos habría que escribir en la línea de comandos las siguientes sentencias:
1) javac -cp d:\java\PaqueteEjemplo\ cCirculo.java
2) javac -cp d:\java\PaqueteEjemplo\ cEntrada.java
//************************************ usaPaquete.java ****************************************
/Descripción: Uso de un paquete simple //Autor: Daniel Leyva Cortés, Contacto: transistor47@hotmail.com //Se importa el paquete completo import Paquete.*; class usaPaquete |
||
public static void main(String args[]) { |
||
double radio; double superficie; cCirculo circ; cEntrada entrada = new cEntrada(); System.out.println("Introduzca el radio del círculo: "); radio = Float.parseFloat(entrada.leeCadena()); //Ahora ya podemos llamar al constructor circ = new cCirculo(radio); superficie = circ.superficie(); System.out.println("La superficie del círculo es : " + superficie); |
||
} | ||
} |
Para compilar este archivo la sentencia sería la siguiente:
javac -cp d:\java\PaqueteEjemplo\ usaPaquete.java
Para ejecutar el archivo:
java -cp d:\java\PaqueteEjemplo\ usaPaquete
EJERCICIO: Crear el paquete "estructuraDatos". Este paquete contendrá las clases "cPila" y "cCola". ç
La clase cPila tendrá que tener implementado los siguientes subprogramas: push (inserta valor en pila), pop (extrae elemento pila), numeroElementos (devuelve el número de elementos de la pila),elemento (devuelve el elemento pero sin destruirlo) y "toString" (visualiza el contenido completo de la pila)
La clase cCola tendrá que tener implementado los siguientes subprogramas: inserta, extrae, numeroElementos y "toString" (visualiza el contenido completo de la cola)
Ambas clases tendrán métodos de inicialización para cada una de las estructura de datos.
Cada objeto tiene su propia copia de las propiedades de la
clase sobre la que se instancia, pero ¿y si nos
interesase que una propiedad fuese común para todos los objetos que perteneciesen
a la misma clase?. Para ello están las propiedades estáticas.
La zona de código donde se inicializan estas propiedades estáticas
se denomina "inicializador estático". Solamente se llamará
una vez al incializador estático.
Los inicializadores estáticos también se usan
para llamar a métodos nativos. Ejemplo:
static
{
System.loadLibrary("libreriaNativa");
}
A continuación se va a ver un ejemplo con sus correspondientes comentarios:
class VariablesStatic |
||
//Métodos para actualizar la propiedad salario y para
devolver el valor actual public void agregaSalario(float valor) { salario+=valor; } public float devuelveSalario() { return(salario); } public static void main(String args[]) { |
||
//Se crean una referencia a la clase |
||
} | ||
} |
Ejercicio 1:
Almacenar los datos de 5 empleados. Se registrarán: apellidos, nif y saldo. Cada vez que se rellenen los datos de un empleado tendrá que actualizarse una propiedad común denominada "saldo total". En cada momento se podrá consultar toda la información que contenga la clase. NOTA: Se tendrá que crear un objeto por empleado.
Ejercicio 2:
Desarrollar clase radio con propiedades x,y, radio (de tipo float); métodos: calculaLongitud (el cálculo es 2*PI*radio), calculaSuperficie (el cálculo es PI*radio*radio). Añadir un método que visualice el número de objetos de esa clase que se hayan creado
Los métodos que acceden únicamente a propiedades estáticas se pueden declarar como métodos estáticos.
Los métodos estáticos lógicamente no podrán usar el operador this.
Veamos un ejemplo de uso:
class MetodosStatic |
||
//Métodos para actualizar la propiedad salario y para devolver el valor actual //IMPORTANTE: Se han declarado los métodos
de tipo estático |
||
//Se crean una referencia a la clase //Directamente se puede poner el nombre de la clase seguido del método |
||
} | ||
} |
Ejercicio 3:
Crear la clase cOperaciones, la cual cuenta con los siguientes métodos estáticos:calculaFactorial y calculaPotencia. También se podrá acceder a una constante que identifique al número PI, ésta estará en la propia definición de la clase
En c++ se puede sobrecargar cualquier operador, sin embargo en JAVA no. Un operador que sí se deja sobrecargar es el operador de concatenación de cadenas.
Si tenemos la siguiente sentencia:
cadenaC = cadenaA + cadenaB
Se interpreta en java de la siguiente manera:
cadenaC = new StringBuffer (cadenaA).append (cadenaB).toString ();