t4 - clases y objetos
TRANSCRIPT
2
Contenidos
1.- Fundamentos de las clases
2.- Sobrecarga de métodos y constructores
3.- Envolventes de tipo, autoencuadre y autodesencuadre
4.- Enumeraciones
5.- Clases predefinidas
4
Una clase es una plantilla que define la forma de un objeto y especifica los atributos o datos (variables) y el código (métodos) que operará sobre esos datos.
Java usa las clases para construir objetos. Los objetos son instancias de una clase.
Por lo tanto, una clase es, en esencia, un conjunto de planos que especifican como construir objetos que comparten las mismas variables y métodos.
Hasta que un objeto de una clase no sea creado, no existe una representación física de esa clase en la memoria.
Los métodos y variables de una clase se llaman miembros de la clase.
Fundamentos de las Clases
5
Una clase se crea empleado la palabra clave Class
class nombre_clase {// declaración de atributos o variables de instancias
tipo var1;tipo var2;
. . . tipo varN;
// declaración de métodostipo metodo1 (parámetros) { // cuerpo del método}tipo metodo2 (parámetros) { // cuerpo del método}
…tipo metodoN (parámetros) { // cuerpo del método}
}
La forma general de una clase
6
class Rectangulo {// variables de instancia
double base, altura;String color;
}
Definición de una clase
Una definición de clase declara un nuevo tipo de datos.
La definición de Class es solo una descripción de un tipo, por lo que no crea un objeto real. Por lo tanto, el código anterior no crea ningún rectángulo.
La definición de una clase Java debe ir en un fichero de texto con extensión .java y nombre idéntico a la clase definida. Por ejemplo, la clase Rectangulo debe ir en un fichero Rectangulo.java.
7
Para crear un objeto Rectángulo, debemos usar la siguiente instrucción:
Rectangulo rectangulo = new Rectangulo( );
• El operador new crea una nuevo objeto (instancia) de la clase Rectángulo.
• Cada objeto de la clase Caja tendrá sus propias copias de las variables ancho, deposito y consumo.
Declaración de una clase
objeto.miembro
Rectangulo1.base = 10;Ejemplo:
Acceso las variables de un objeto. Para acceder a las variables miembro usaremos el operador punto (.) de la siguiente forma.
8
// Este programa crea objetos de la clase Rectángulo
class RectanguloDemo {
public static void main( String args[ ] ) {
Rectangulo rect1 = new Rectangulo ( );
// asignamos valores al objeto rectangulo1
rect1.base = 10; // usamos el operador punto para
rect1.altura = 5; // acceder a cada miembro
rect1.color = “Rojo”;
// calculamos el área del objeto rectacgulo1;
double area = rect1.base * rect1.altura;
// mostramos los resultados
System.out.println(“Área rectángulo ” + rect1.color +
“ = ” + area);
}
}
Definición de una clase
9
El nombre del archivo fuente debe ser RectanguloDemo.java porque el método main esta es dicha clase.
Al compilar el programa se generan dos archivos .class, uno por cada clase que ha sido definida: Rectangulo.class y RectanguloDemo.class.
No es necesario que el código fuente de ambas clases estén en el mismo archivo, podrían estar en archivos separados.
Para ejecutar el programa, debemos ejecutar RectanguloDemo.class, que mostrará la siguiente salida:
Área del rectángulo Rojo = 15.0
Declaración de una clase
Cada objeto tiene sus propias copias de las variables de instancia definidas en la clase. Por lo tanto el contenido de las variables de un objeto pueden ser diferentes de las de otro de la misma clase.
10
Ejemplo:
class DosRectangulos {public static void main(String args[]) {
Rectangulo r1 = new Rectangulo();Rectangulo r2 = new Rectangulo();
r1.base = 10.0; r1.altura = 5.0; r1.color = “Rojo”;
r2.base = 15.2; r2.altura = 7.5; r2.color = “Verde”;
double area1 = r1. base * r1.altura;double area2 = r2. base * r2.altura;
System.out.println(“Área rectángulo ” + r1.color + “ = ” area1);
System.out.println(“Área rectángulo ” + r2.color + “ = ” area2);
}}
Declaración de una clase
11
Creamos una instancia de la clase Rectángulo con la instrucción:
Rectangulo rect1 = new Rectangulo ( );
Cómo se crean los objetos
o también así
Rectangulo rect1; // declaración
rect1 = new Rectangulo( ); // creación de objeto
Rectangulo rect1
rect1
null
• Declara rect1 como una variable que hace referencia a un objeto de la clase Rectangulo, pero no es un objeto en sí. rect1 contiene un valor null.
Rect1 = new Rectangulo();
rect1Objeto rect1
• El operador new crea un objeto de la clase Rectangulo y asigna a la variable rect1 una referencia a dicho objeto. Ahora, rect1 esta vinculado con un objeto.
base 0.0
altura 0.0
Color
12
Las variables de referencia a objetos actúan de diferente manera a como lo
hacen las variables de tipo primitivo (int, double, char, ...).
Consideremos el siguiente fragmento de código:
Rectangulo r1 = new Rectangulo ( );
Rectangulo r2 = r1; // la variable de referencia r2 se refiere a r1
r1.base = 5;
Variables de referencia y asignación
Comprobemos lo que guardan:
System.out.println(r1.base);
System.out.println(r2.base);
En ambos casos nos devolverá un valor de 5. Ambas variables r1 y r2 es que se refieren al mismo objeto. Podremos actuar sobre el
mismo objeto mediante r1 o r2.
13
Rectangulo r1 = new Rectangulo ( );
Rectangulo r2 = r1;
Rectangulo r3 = new Rectangulo ( );
r1.base = 5; r3.base = 12.5;
r2 = r3;
A r2 se le cambia la referencia del objeto al que se refiere.
base 5
altura
colorr1
base 12.5
altura
color
r2
r3
Variables de referencia y asignación
14
Métodos
Como ya se explicó, las variables de instancia y los métodos son los miembros de una clase. Hasta ahora la clase Rectángulo contiene datos, pero no métodos.
Los métodos son subrutinas de código que manipulan los datos definidos por la clase y, en muchos casos, proporcionan acceso a esos datos. En la mayoría de los casos, otras partes de un programa interactúan con una clase a través de sus métodos.
Un método contiene una o más instrucciones. En un código Java bien escrito, cada método sólo realiza una tarea y tiene un nombre, que se utiliza para llamar al método.
En general, podemos asignarle a un método el nombre que queramos, excepto main(), que está reservado para el método principal que inicia la ejecución de un programa. Tampoco podemos asignar a un método el nombre de una palabra reservada.
15
La forma general de un método es:
tipo_retorno nombre ( lista_parámatros ) {
// cuerpo del método
}
Métodos
• El tipo_retorno es el tipo de valor devuelto por el método. Si el método no devuelve un valor, su tipo de retorno debe ser void.
• La lista_parametros es una lista de pares de tipo - identificador, separados por comas. Si el método no tienen parámetros, la lista de parámetros estará vacía.
• Los parámetros son variables que reciben el valor de los argumentos que se pasan al método cuando ese es llamado.
• Habitualmente, los métodos de una clase manipulan y proporcionan acceso a los datos de la clase.
16
class Rectangulo { double base, altura; String color; // método para calcular el área void area( ) { System.out.println(“Área = ” + base * altura); }}
Las variables de instancia base y altura dentro del método area son referidas sin hacer uso del operador punto. Esto es así porque para el método son variables de instancia definida por su clase.
Añadir un método a una clase
Para añadir un método a nuestra clase Rectángulo deberemos especificarlo dentro de la definición de la clase. Veamos como:
17
Llamar a un método a una clase
// Llamada a un método de una clase
class AgregarMetodo {public static void main(String args[]) {
Rectangulo r1 = new Rectangulo();
// asignamos valores a las varibles de instanciar1.base = 10.0;r1.altura = 5.0;r1.color = “Rojo”;
// Mostramos el color y área del rectánguloSystem.out.println(“Rectángulo ” + r1.color +
“ ” r1.area());}
}La llamada al método area del objeto r1 de la clase Rectangulo mostrará “Área = 15”
18
Un método finalizará, bien porque alcanza la llave de cierre del método o porque se encuentra con un return dentro del código.
En ambos casos, se produce la terminación del método y el control del programa se devuelve a quien realizó la llamada al método.
Un método con tipo de retorno void terminará al alcanzar la llave de cierre o al ejecutar una instrucción return.
Regreso de un método.
Hay dos formas de return:
• Para usarlo en métodos void (los que no devuelven valor).• Para usarlos en métodos que devuelven un valor.
19
class Rectangulo { double base, altura;
String color;
// Método que devuelve el área del rectángulo double area( ){
return base * altura; //devuelve el área }
}
Devolución de un valor
Los métodos pueden devolver un valor a quien les llama usando la sentencia return de la forma:
return valor;
La ventaja de este cambio es que aporta flexibilidad al método, ya que podremos utilizarlo en más ocasiones, donde necesitemos el valor del área para otros cálculos y donde pretendamos mostrarlo como tal característica del objeto.
20
Devolución de un valor
// Devolución de un valor por un método
class DevuelveValor {public static void main(String args[]) {
Rectangulo r1 = new Rectangulo();
// asignamos valores a las varibles de instanciar1.base = 10.0; r1.altura = 5.0;r1.color = “Rojo”;
// Mostramos el color y área del rectánguloSystem.out.println(“Área rectángulo ” + r1.color +
“ = ” r1.area() );}
}La llamada al método devolverá el área del rectángulo
21
Es posible pasar uno o más valores a un método cuando este es llamado. El valor pasado a un método es un argumento. Dentro del método, la variable que recibe el argumento es un parámetro.
Los parámetros se declaran dentro del paréntesis que sigue al nombre del método.
La sintaxis para declarar parámetros es la misma que hemos visto para la declaración de variables.
tipo parámetro, tipo parámetro, …
Un parámetro se encuentra dentro del alcance del método y se comporta como cualquier otra variable local dentro del método.
Uso de parámetros
22
Vamos crear un método llamado EsPar que compruebe si el número que recibe como argumento es un número par o impar.
class ComNum {boolean esPar (int x){ // x es un parámetro de
esPar if ( x % 2 == 0 ) return true; else return false;}
}
class ParamDemo1 {public static void main(String args[]){ ComNum n = new ComNum(); if (n.esPar(10) System.out.println(“10 es Par”);}
}
Uso de parámetros
23
Un método puede tener más de un parámetro, basta declararlos separados por comas.
class Divisor {boolean EsDivisor(int n, int d){ // dos parámetros if (n % d == 0) return true; else return false;}
} class ParamDemo2 { public static void main(String[] args){
Divisor n = new Divisor(); if (n.EsDivisor(20,2)) System.out.println(“2 es
divisor”); }
}
Uso de parámetros
24
Un constructor inicializa un objeto cuando éste se crea. Tiene el mismo nombre de su clase y es sintácticamente similar a un método. Sin embargo, los constructores no tienen un tipo de retorno.
Por lo general, usaremos un constructor para dar valores iniciales a las variables de instancia definidas por la clase, o para realizar cualquier otra acción de inicio que se requiera para crear un objeto.
Todas las clases tiene constructores, ya sea porque el programador los defina, o porque Java proporciona un constructor por defecto que inicializa todas las variables miembro.
Constructores
25
Cuando a una clase se le define un constructor, el constructor por defecto no se usa nunca.
class MiClase {int x, y;
// Un constructor simple para MiClaseMiClase( ) { // sin parámetros x = 10; y = 5;}
}
Constructores
26
El constructor de la clase será llamado cuando creemos un objeto de la clase con el operador new.
class ConsDemo{ public static void main (String args[ ]) {
MiClase t1 = new MiClase( );MiClase t2 = new MiClase( );
/* El constructor MiClase( ) crea el t1 y t2 y da valores a las variables.*/
System.out.println(“Valores t1: ” + t1.x + “ ”+ t1.y ;
System.out.println(“Valores t2: ” + t2.x + “ ”+ t2.y); } }
Resultado: Valores t1: 10 5Valores t2: 10 5
Constructores
27
Los parámetros se añaden a los constructores de la misma forma que se hace con un método: se declaran dentro de paréntesis después del nombre del constructor.
Constructores
class ConsDemo{ public static void main (String args[ ]) { MiClase t1 = new MiClase(10, 15); System.out.println(“Valores t1 : ” + t1.x + “ ”+ t1.y ; }}
class MiClase {int x, y;MiClase(int x, int y) { // con parámetros x = 10; y = 5;}
}
28
class Rectangulo {double base, altura; String color;
// constructor de la clase RectanguloRectangulo (double b, double h, String c){ base = b; // inicializa la base altura = h; // inicializa la altura color = c // inicializa el color } double area() { return base * altura; }
}
Constructores
Podemos mejorar la clase Rectangulo agregando un constructor.
29
Constructores
// Uso de un constructor con parámetros
class ConsRectDemo{ public static void main (String[] args) { /*Construimos dos rectángulos con sus valores de base, altura y color iniciales */
Rectangulo r1 = new Rectangulo(10.0, 15.0, “Rojo”);Rectangulo r2 = new Rectangulo(7.5, 5.2, “Azul”);
System.out.println( “Rectangulo + ” r1.color) ; System.out.println( “Area: ” + r1.area) ;
System.out.println( “Rectangulo + ” r2.color) ; System.out.println( “Area: ” + r2.area) ;
}}
30
Ahora que sabemos más de las clases y sus constructores, echemos un vistazo al operador new. Su forma general es:
NombreClase variableReferencia = new NombreClase( );
NombreClase es la clase que será instanciada.variableReferencia es el nombre del objeto que se crea.NombreClase( ) es el constructor de la clase.
Si una clase no define su propio constructor, new usará el constructor por defecto que proporciona Java. De este modo, new puede usarse para crear un objeto de cualquier tipo de clase.
El operador new asigna memoria dinámicamente para almacenar los objeto creados. Cuando no se puede asignar memoria a un objeto, ocurrirá una excepción (error) en tiempo de ejecución.
El operador new
33
Cuando se llama a un método, se pasa automáticamente un argumento implícito que es una referencia al objeto en el que se llama al método. Esta referencia se llama this.
Por tanto, la palabra this puede ser utilizada dentro de cualquier método para referirse al objeto actual que invocó al método.
La palabra clave this
// Colisión de nombres. Esto es INCOCORRECTO Rectangulo (double base,double altura,String color){ base = base; altura = altura; color = color }
Cuando una variable local de un método tiene el mismo nombre que una variable de instancia, la variable local oculta a la variable de instancia. El siguiente ejemplo es incorrecto:
Colisión de nombres: Como los parámetros son iguales a las variables de instancia, estás quedan ocultas y los valores no pueden asignarse.
34
Si queremos usar parámetros con nombres iguales a las variables de instancia debemos usar this.
this permite hacer referencia directamente al objeto y resolver la posible colisión de nombres que pudiera darse entre las variables de instancia y las variables locales.
// Uso de this para resolver colisiones. CORRECTORectangulo(double base, double altura, String
Color){ this.base = base; this.altura = altura; this.color = color;}
La palabra clave this
Esto se refiere a la variable de instancia color no al parámetro
En esta versión del constructor Rectangulo() los parámetros son los mismos que los de las variables de instancia, pero estas ultimas, están ocultas, sin embargo, this se usa para “descubrir” las variables de instancia.
35
El control de acceso a miembros de una clase se logra mediante el uso de tres modificadores de acceso: public, private y protected.
Modificadores de acceso de Java
La modificación del acceso a un miembro de clase mediante se realiza en su declaración. La sintaxis es:
modificador miembro_clase
El modificador protected sólo se aplica cuando se utiliza herencia; lo explicaremos en el tema de herencia.
Una parte fundamental de la programación orientada a objetos es el acceso restringido a los miembros de una clase, lo que ayuda a prevenir el mal uso de un objeto.
36
Un miembro de clase definido como public puede ser accedido desde cualquier otra parte del código del programa. Esto incluye métodos definidos en otras clases.
public double area() …
Modificadores de acceso de Java
Un miembro de una clase definido como private, sólo es accesible desde otros miembros de su misma clase. Así, los métodos en otras clases no pueden acceder a los miembros private de una clase directamente.
private double base;
La única forma de accede a un atributo privado de una clase A desde otra
clase B es a través de algún método publico de la clase A. El modificador de acceso predeterminado es public, a menos que el
programa este dividido en paquetes. Un paquete agrupa clases y constituye un medio para organizar y controlar el acceso.
37
// Uso de modificadores de accesoClass Rectangulo{ private double base, double altura;// acceso privado// métodos public double area( ) { // calcula el área
return base * altura; }// Propiedades . . . . . . . . . . . . . . . . public void setBase(double a) { // asigna el valor de base
base = a; } public void setAltura(double h) { //asigna el valor de altura altura = h; } public double getBase() { // devuelve la base
return base; } public double getAltura() { // devuelve altura return altura; }}
Modificadores de acceso de Java
38
class AccesoDemo { public static void main ( String args[ ] ) { Rectangulo r1 = new Rectangulo( );
//No se puede tener acceso de la siguiente manera
r1.base = 10.0; // INCORRECTO!!!, base es privado
// Acceso correcto a base y altura r1.SetBase(10.0); // correcto, SetBase es publico r1.SetAltura(5.7); // correcto, SetAltura es publico
// acceso correcto a area, método público System.out.println(“Area = ” + r1.area()); }}
Modificadores de acceso de Java
39
El modificador static
En general, un miembro de clase debe ser accedido a través de un objeto de su clase; sin embargo, es posible crear un miembro que pueda utilizarse por sí solo, desde la propia clase, sin referencia a una instancia específica.
Cuando la declaración de un miembro va precedida de la palabra clave static, se podrá acceder a ese miembro antes de que cualquier objeto de su clase se cree, y sin referencia a ningún objeto.
La declaración de static se puede aplicar a variables y a métodos.
El ejemplo más habitual de miembro static es el método main( ), que se declara como tal porque debe ser llamado antes de que exista cualquier objeto.
40
Las variables declaradas como static son, en esencia, variables globales. Cuando se declara un objeto no se hace ninguna copia de las variables static. Todas las instancias de la clase comparten la misma variable static.
Los métodos static se cargan en memoria a iniciarse la ejecución de un programa y están siempre disponibles. No es necesario crear una instancia de la clase en al que están definidos para utilizarlos.
El modificador static
Fuera de la clase, para usar un miembro static sólo es necesario especificar el nombre su clase seguido por el operador punto. No es necesario crear ningún objeto.
nombre_clase.miembro_static( )
41
class StaticDemo { static int a = 42; static int b = 99; static void llamame ( ) { System.out.println(“ a = ” + a ); }}
class StaticPorNombre { public static void main (String args[ ]) { StaticDemo.llamame(); System.out.println(“ b = ” + StaticDemo.b ); }}
Salida: a = 42b = 99
El modificador static
42
class StaticDemo2 { int x; // variable de referencia normal static int y; // variable static}
class SDemo { public static void main (String args[ ]) { StaticDemo2 ob1 = new SytaticDemo2(); StaticDemo2 ob2 = new SytaticDemo2();
ob1.x = 10; ob2.x = 20;
System.out.println(“Ob1.x y Ob2.x son independientes”); System.out.println(“Ob1.x : ” + ob1.x + “ ob2.x: ” + ob2.x);
. . .
El modificador static
43
. . .
/*Cada objeto comparte una sola copia de una variable static */ System.out.println(“\nSe comparte la variable y”); ob1.y = 19; System.out.println(“ob1.y :” + ob1.y + “ ob2.y: ” + ob2.y); System.out.println(“\nAcceso a y mediante su clase”); StaticDemo2.y = 11; System.out.println(“StaticDemo2.y: ” + StaticDemo2.y); System.out.println(“ob1.y : ” + ob1.y + “ ob2.y: ” + ob2.y); }}
El modificador static
La salida de SDemo será:
Ob1.x y Ob2.x son independientes ob1.x = 10 ob2.x = 20
Se comparte la variable y ob1.y = 19 ob2.y = 19
Acceso a y mediante su clase StaticDemo2.y = 11ob1.y = 11 ob1.y = 11
44
// ejemplo de método static ilegalclass StaticError { int denom = 3; // variable de referencia normal static int val = 1024; // variable static
/* Error!!! No se puede acceder a variables static ,desde un método static */
static int valDivDenom ( ) { return val / denom; // denom NO es static, no compila !!!! }}
El modificador static
Los miembros declarados como static tiene varias
restricciones:• Sólo pueden llamar a otros métodos static• Sólo pueden acceder a datos static• No pueden tener referencia this
45
A veces puede ser necesario inicializar ciertas variables static antes de que se emplee cualquiera de los métodos static de la clase. Para estas situaciones, Java permite declarar un bloque static que se ejecuta cuando se carga la clase por primera vez, antes de que la clase pueda emplearse para cualquier otro fin.
Bloque static
// Uso de un bloque staticclass StaticBloque { static double raizde2, static double raizde3; static { System.out.println(“Dentro del bloque static.”); raizde2 = Math.sqrt(2.0); //método sqrt de la clase Math raizde3 = Math.sqrt(3.0); } static class mensaje(String msj){ System.out.pritln(msj); }}
46
Class RaizDemo { public static void main (String args[ ]) { StaticBloque.mensaje(“Ejemplo de Static”); System.out.prinln(“Raíz cuadrada de 2: ” +
StaticBloque.raizde2); System.out.prinln(“Raíz cuadrada de 3: ” +
StaticBloque.raizde3); }}
Se muestra la salida:Ejemplo de staticRaíz cuadrada de 2: 1.4142135623730951Raíz cuadrada de 3: 1.7320508075688772
No ha sido necesaria la ínstanciación de un objeto de la clase para ejecutar el programa, ya que todos los miembros de la clase han sido declarados static.
Bloque static
47
El modificador final
Declarando una variable como final se impide que su contenido sea modificado. Esto implica que estas variables deben ser inicializadas cuando son declaradas.
final int PI = 3.1416;
Un convenio muy utilizado en programación es el de utilizar nombres en mayúsculas para las variables final.
El uso de la palabra clave final con los métodos se verá en el tema de herencia.
49
Resulta correcto y muy común pasar objetos a métodos.
Paso de objetos a métodos
class Rectangulo {double base, altura;
Rectangulo(double b, double h) {base = b; altura = h;
}
boolean mismoRectangulo(Rectangulo ob){ //parámetro objeto return (ob.base == base) & (ob.altura == altura);}
}
50
class pasaObjeto { public static void main ( String args[ ] ) { Rectangulo r1 = new Rectangulo( 10.0, 5.0 ); Rectangulo r2 = new Rectangulo( 10.0, 5.0 ); Rectangulo r3 = new Rectangulo( 6.0, 5.0 );
System.out.println (“r1 mismo tamaño que r2: ” r1.mismoRectangulo(r2));
System.out.println (“r1 mismo tamaño que r3: ” r1.mismoRectangulo(r3));
}}
Paso de objetos a métodos
La salida que genera el programa es:r1 mismo tamaño que r2: truer1 mismo tamaño que r3: false
51
Java ofrece dos formas de pasar un argumento a un método, llamada por valor y llamada por referencia, según sea el argumento que se pasa.
En una llamada por valor se copia el valor del argumento en el parámetro del método cuando este es llamado. Los cambios realizados en parámetro del método no tiene efecto en el argumento de la llamada.
En una llamada por referencia, se pasa una referencia del argumento (no su valor) al parámetro. Dentro del método, esta referencia se usa para acceder al argumento pasado en la llamada. Los cambios realizados al parámetro afectarán al argumento de la llamada.
En Java, los argumentos de tipos primitivos (int, double, etc) siempre se pasan por valor a los métodos.
Cómo se pasan los argumentos
52
class Prueba { void NoCambia (int i,int j) {// i y j son parámetros por valor
i = i * 2;j = - j;
}}class LlamadaPorValor { public static void main(String args[]){
Prueba ob = new Prueba();int a = 15, b = 20;System.out.println(“a y b antes de la llamada: ” + a +“ ” + b );ob.NoCambia(a,b);System.out.println(“a y b después de la llamada: ”+ a +“ ” + b)
}}
Cómo se pasan los argumentos
La salida que genera el programa es:a y b antes de la llamada : 15 20a y b después de la llamada : 15 20
53
Los argumentos objetos siempre se pasan por referencia a los métodos.
Recordamos que cuando se crea una variable de un tipo clase, sólo se crea una referencia a un objeto. Por lo tanto, cuando se pasa una variable de referencia a un método, el parámetro que la recibe, se referirá al mismo objeto. Por lo tanto:
Los cambios que se realicen al objeto dentro del método afectarán al objeto usado como argumento.
Cómo se pasan los argumentos
Para pasar un tipo primitivo por referencia, java define las clases envolventes Double, Float, Byte, Short, Integer, Long y Character, que además, implementan varios métodos para manipular sus valores.
54
// Los objetos siempre se pasan por referenciaclass Prueba {
int a, b;Prueba (int i, int j) {
a = i; b = j;}void cambio(Prueba ob) { // Pasa un objeto. ob.a = ob.a + ob.b; ob.b = -ob.b;}
}
Cómo se pasan los argumentos
class LlamadaPorReferencia { public static void main ( String args[ ] ) {
Prueba ob = new Prueba(15,20);System.out.println(“ob.a y ob.b antes: ” + ob.a + “ ” + ob.b );ob.Cambio(ob);System.out.println(“ob.a y ob.b después: ” + ob.a + “ ” + ob.b );
}}
La salida que genera el programa es:ob.a y ob.b antes: 15 20ob.a y ob.b después: 35 -20
55
Un método puede devolver cualquier tipo de datos, incluyendo objetos de clases definidas por el programador.
Devolución de objetos
class Test{ int a; Test (int i) { //constructor a = i ; } Test increnDiez(){ // Devuelve un objeto Test // incrementa en 10 unidades el valor del atributo a Test temp = new Test(a + 10); return temp; }}
56
// Devolución de objetosclass DevuelveObjeto { public static void main(String args [ ] ) {
Test ob1 = new Test(2); Test ob2;
ob2 = ob1.increnDiez(); System.out.println(“ob1.a: ” + ob1.a ); System.out.println(“ob2.a: ” + ob2.a );
ob2 = ob2.increnDiez( ); System.out.println(“ob2.a después del 2º inc.:” + ob2.a); }}
Devolución de objetos
La salida que genera el programa es:ob1.a: 2ob2.a: 12ob2.a después del 2º incremento :22
58
En Java es posible definir dos o más métodos que compartan el mismo nombre, dentro de la misma clase, pero con distintos parámetros. Cuando se produce esta situación, se dice que los métodos están sobrecargados, y que el proceso es una sobrecarga de método.
La sobrecarga de métodos es una de las formas en que Java implementa el polimorfismo.
Cuando se invoca a un método sobrecargado, Java utiliza el tipo y/o número de argumentos como guía para determinar a qué versión del método sobrecargado se debe llamar. Por lo tanto, los métodos sobrecargados deben diferir en el tipo y/o número de sus parámetros.
Sobrecarga de métodos
59
El tipo que devuelve un método, por sí solo es insuficiente para distinguir dos versiones diferentes de un método.
Cuando Java encuentra una llamada a un método sobrecargado, se ejecuta la versión del método cuyos parámetros coinciden con los argumentos utilizados en la llamada.
Veamos un ejemplo que ilustra la sobrecarga de métodos...
Sobrecarga de métodos
60
// Ejemplo de sobrecarga de métodosclass SobrecargaDemo {
void test ( ) {System.out.println(“ Sin parámetros”);
}// Sobrecarga con un parámetro entero void test ( int a ) {
System.out.println(“ a : ” + a );}// Sobrecarga con dos parámetros enteros void test ( int a, int b ) {
System.out.println(“ a y b : ” + a + “ ” + b );}// Sobrecarga con un parámetro doubledouble test ( double a ) {
System.out.println(“ a double : ” + a );return a*a;
} }
Sobrecarga de métodos
61
class Sobrecarga {public static void main ( String args[ ] ) {
SobrecargaDemo obj = new SobrecargaDemo( );double resultado;// llamada a todas las versiones de testobj.test( );obj.test( 10 );obj.test( 10, 20 );resultado = obj.test( 123.25 );System.out.println(“Resultado : ”+ resultado );
}}
Sobrecarga de métodos
62
El programa produce la salida :
Sin parámetros a : 10 a y b : 10 20 a double : 123.25
Resultado de obj.test(123.25) : 15190.5625
Cuando se llama a un método sobrecargado, Java busca las coincidencias entre los argumentos utilizados en la llamada y los parámetros del método.
Esta coincidencia no es preciso que sea siempre exacta. En algunos casos se puede aplicar la conversión automática de tipos de Java.
Sobrecarga de métodos
63
// aplicación de la conversión automática de tipos en la sobrecargaclass SobrecargaDemo {
void test ( ) {System.out.println(“ Sin parámetros”);
}// Sobrecarga con dos parámetros enteros void test ( int a, int b ) {
System.out.println(“ a y b : ” + a + “ “ + b );}// Sobrecarga con un parámetro doubledouble test ( double a ) {
System.out.println(“ Dentro del test (double) a: ” + a );return a*a;
}}
Sobrecarga de métodos
64
class Sobrecarga2 {public static void main ( String args[ ] ) {
SobrecargaDemo obj = new SobrecargaDemo( );int i = 88;
obj.test( );obj.test( 10, 20 );
obj.test( i ); // llamada a test ( double )obj.test( 123.2 ); // llamada a test ( double )}
}
Sobrecarga de métodos
65
La salida generada por el programa es:
Sin parámetros a y b : 10 20 Dentro del test (double) a: 88.0 Dentro del test (double) a: 123.2
Consideraciones sobre la sobrecarga:
• Cuando se sobrecarga un método, cada versión de ese método debe relacionarse con las demás.
• Aunque se puede utilizar el mismo nombre para sobrecargar métodos que no estén relacionados, no se debe hacer.
• En la práctica, sólo se deben sobrecargar operaciones estrechamente relacionadas.
Sobrecarga de métodos
66
Sobrecarga de métodos
Ejemplo:
class Plano3D { double a, b, c, d; Plano3D (double aa, double bb, double cc, double dd) { a = aa; b = bb; c = cc; d = dd; } boolean paralelo (Plano3D p) { Vector3D u = new Vector3D (a, b, c); Vector3D v = new Vector3D (p.a, p.b, p.c); return u.paralelo (v); } boolean paralelo (Recta3D r) { Vector3D u = new Vector3D (a, b, c); return u.perpendicular (r.vector); }}
67
Sobrecarga de métodos
class Vector3D { double x, y, z;
Vector3D (double xx, double yy, double zz) { x = xx; y = yy; z = zz; }
Vector3D (Punto3D p, Punto3D q) { x = q.x - p.x; y = q.y - p.y; z = q.z - p.z; }
boolean paralelo (Vector3D u) { return (x * u.y == y * u.x) && (x * u.z == z * u.x); }
boolean perpendicular (Vector3D u) { return productoEscalar (u) == 0; }}
68
Sobrecarga de métodos
class Recta3D { Punto3D punto; Vector3D vector; Recta3D (Punto3D p, Vector3D v) { punto = p; vector = v; }}
// Bloque mainPlano3D p1 = new Plano3D (2, 4, 3, 1);Plano3D p2 = new Plano3D (1, 0, -2, 1);Recta3D r = new Recta3D (new Punto3D (1, 0, 1), new Vector3D (1, 1, -1));p1.paralelo (p2);p1.paralelo (r);
69
Además de sobrecargar los métodos normales, también se pueden sobrecargar métodos constructores. Sea la definición de la clase caja:
class Caja {double ancho; double alto; double largo;
// constructor de la claseCaja ( double w, double h, double d ) {
ancho = w;alto = h; largo = d;}
// cálculo y devolución del volumendouble volumen ( ) {
return ancho * alto * largo;}
}
Sobrecarga de constructores
70
El constructor de Caja( ) requiere tres parámetros. Esto significa que todas las declaraciones de objetos Caja deben pasar tres argumentos al constructor de Caja:
Caja ( double w, double h, double d )
La siguiente sentencia no es válida:Caja obj = new Caja ( );
Esta situación plantea algunas cuestiones como:• Si solo se necesita una caja, sin importar las dimensiones
iniciales.• Si se necesita una caja con forma de cubo, solo necesita 1
dimensión. Esta situaciones no se contemplan en la definición actual de la clase.
Veamos una versión mejorada:
Sobrecarga de constructores
71
class Caja {double ancho, alto, largo;// constructores de la claseCaja ( double w, double h, double d ) {
ancho = w; alto = h; largo = d;}Caja ( ) { // el valor –1 indica que la caja no está
inicializadaancho = -1; alto = -1; largo = -1;
}Caja ( double lado ) { // para un con forma de cubo
ancho = alto = largo = lado;}
// cálculo y devolución del volumendouble volumen ( ) {
return ancho * alto * largo;}
}
Sobrecarga de constructores
72
class DemoCaja {public static void main (String args [ ] ) {
Caja Caja1 = new Caja ( 10, 20, 15 );Caja Caja2 = new Caja ( );Caja Cubo = new Caja ( 7 );double vol;
vol = Caja1.volumen();System.out.println(“Volumen de Caja1 : ” +
vol );
vol = Caja2.volumen();System.out.println(“Volumen de Caja2 : ” +
vol );
vol = Cubo.volumen();System.out.println(“Volumen de Cubo : ” + vol );
}}
Sobrecarga de constructores
73
La salida que produce el programa es:
Volumen de Caja1 : 3000.0Volumen de Caja2 : -1.0Volumen de Cubo : 343.0
Con este constructor sobrecargado, la llamada al método se basa en los parámetros especificados cuando se ejecuta el operador new.
De esta manera se le da al usuario una flexibilidad de clase en la forma como son construidos los objetos.
Una de las razones más comunes para que los constructores sean sobrecargados es permitir que un objeto inicialice a otro.
Sobrecarga de constructores
74
// inicialización de un objeto con otro
class Sumador {int suma;
Sumador ( int num ) {suma = 0;for ( int i = 0; i < = num ; i++)
suma += 1;}
Sumador ( Sumador obj) {suma = obj.suma;
}}
Sobrecarga de constructores
75
class SumaDemo {public static void main ( String args [ ] ) {
Sumador s1 = new Sumador ( 5 );Sumador s2 = new Sumador ( s1 );
System.out.println(“s1.suma : ” + s1.suma);System.out.println(“s2.suma : ” + s2.suma);
}}
La salida del programa es:
s1.suma : 5s2.suma : 5
Sobrecarga de constructores
76
La clase Date y GregorianCalendar
Ejemplo: //* Formatear una fecha como se desee*/ public class Fechas3 {
public static void main(){ Date hoy = new Date(); // creamos un objeto fecha Locale fEspañol = new Locale("es", "ES", "Traditional_WIN"); String fechaC = DateFormat.getDateInstance(DateFormat.SHORT, fEspañol).format(hoy); String fechaM = DateFormat.getDateInstance(DateFormat.MEDIUM, fEspañol).format(hoy); String fechaL = DateFormat.getDateInstance(DateFormat.LONG, fEspañol).format(hoy); String fechaCO = DateFormat.getDateInstance(DateFormat.FULL, fEspañol).format(hoy);
DateFormat formato = new SimpleDateFormat("EEEE d 'de' MMMM 'de' yyyy", fEspañol); String fechaLB = formato.format(hoy);
System.out.println("Fecha corta: " + fechaC + “\tFecha media: " + fechaM); System.out.println("Fecha Larga: " + fechaL); System.out.println("Fecha Completa: " + fechaCO); System.out.println("Fecha Libre: " + fechaLB);
}
La salida es:Fecha corta: 25/07/07 Fecha media: 25-jul-2007Fecha Larga: 25 de julio de 2007Fecha Completa: miércoles 25 de julio de 2007Fecha Libre: miércoles 25 de julio de 2007
78
Envolventes de tipo
A veces necesitaremos representar uno de los tipos primitivos Java como un objeto. Por ejemplo, para pasar un tipo primitivo por referencia a un método.
Además, muchas estructuras de datos Java, como las colecciones, operan sobre objetos, lo que significa que no podemos usarlas para almacenar tipos primitivos.
Para manejar estas situaciones, Java proporciona envolventes de tipo (wrappers), que son clases que encapsulan un tipo primitivo dentro de un objeto.
Las envolventes de tipo son: Byte, Short, Integer, Long, Float, Double, Character y Boolean.
79
Envolventes de tipo
Casi siempre, suelen tener los siguientes métodos:
• Constructores que reciben un String o un tipo primitivo:
Integer a = new Integer(3);
• Convertidores de tipo String a su tipo envolvente numérico:
Integer b = Integer.valueOf(“3”);
• Convertidores de tipo String al tipo primitivo que representan:
int c = Integer.parseInt(“3”);
• Convertidores de un tipo primitivo numérico a String:
String d = Integer.toString(c);
• Extractores del tipo primitivo que representan:
int e = b.intValue();
80
Todas estas conversiones de tipo pueden producir errores. ¿Qué pasaría si se intenta crear un Integer utilizando “Hola” como parámetro?
Siempre que la conversión no sea posible, la JVM lanzará una excepción (un error) del tipo java.lang.NumberFormatException
Envolventes de tipo
Todos las envolventes de tipo sobrescriben el método equals de la clase java.lang.Object.
Ejemplo:
Integer i1 = new Integer(3);Integer i2 = new Integer(3);
System.out.println(i1 == i2);System.out.println(i1.equals(i2));
De esta forma, podemos saber si dos objetos distintos de un mismo tipo envolvente, representan el mismo valor primitivo o no.
81
Clases envolventes de tipo
Métodos principales de las clases envolventes:
String toString(short s) Convierte un valor de tipo short en una cadena
Short valueOf(String s) Obtiene un objeto Short a partir de una cadena
float parseFloat(String s) Convierte una cadena numérica en un valor de float
String toString(float f) Convierte un valor de tipo float en una cadena
Float valueOf(String s) Obtiene un objeto Float a partir de una cadena
double parseDouble(String s) Convierte una cadena numérica en un valor double
String toStringDouble(duble d) Convierte un valor de tipo double en una cadena
Double valueOf(String s) Obtiene un objeto Double a partir de una cadena
82
int parseInt(String s) Convierte una cadena numérica en un valor int
String toString(int i) Convierte un valor de tipo int en una cadena
Integer valueOf(String s) Obtiene un objeto Integer a partir de una cadena
double parseDouble(String s) Convierte una cadena numérica en un valor double
String toString(long i) Convierte un valor de tipo long en una cadena
Long valueOf(String s) Obtiene un objeto Long a partir de una cadena
byte parseByte(Strint s) Convierte una cadena numérica en un valor byte
String toString(byte b) Convierte un valor de tipo byte en una cadena
Byte valueOf(String s) Obtiene un objeto Byte a partir de una cadena
short parseShort(Sring s) Convierte una cadena numérica en un valor short
Métodos principales de las clases envolventes:
Clases envolventes de tipo
83
Ejemplos:
int año;double numero;String sNumero = “1245.67”, cadena;
// convierte la cadena “2007” en un valor intaño = Integer.parseInt(“2007”);
// convierte la cadena numérica sNumero en un valor doublenumero = Double.parseDouble(sNumero);
// convierte año de tipo int a la cadena numérica “2007”cadena = toString(año);
Clases envolventes de tipo
92
Envolvente de Tipo. Ejemplo
// Uso de clases envolventespublic class EnvolventesTest {
public static void main(String[] args){String texto = new String("3");byte b = Byte.parseByte(texto);System.out.println(Byte.toString(b));short s = Short.parseShort(texto);System.out.println(Short.toString(s));int i = Integer.parseInt(texto);System.out.println(Integer.toString(i));long l = Long.parseLong(texto);System.out.println(Long.toString(l));float f = Float.parseFloat(texto);System.out.println(Float.toString(f));double d = Double.parseDouble(texto);System.out.println(Double.toString(d));
}}
93
Las funciones autoencuadre y auto-desencuadre convierten tipos primitivos en objetos envolventes de tipo y viceversa.
El autoencuadre (autoboxing) encapsula (encuadra) un valor de tipo primitivo en su envolvente del tipo equivalente cuando se requiere un objeto de ese tipo.
El auto-desencuadre (auto-unboxing) extrae (desencuadre) el valor de un tipo primitivo de su envolvente de tipo cuando se requiere un valor de ese tipo.
Ejemplos:
// Crea un objeto Integer a partir de un int Integer iOb = 100; // autoencuadra un int
Autoencuadre / Autodesencuadre
// Extrae un tipo int de su envolvente int a = iOb; // autodesencuadra un objeto Integer
94
Java realiza el autoencuadre y autodesencuadre de forma automática.
Esto nos permite también operar con los envolventes.
Integer a = 10; Integer b = 3; int c = a + b;
Autoencuadre / Autodesencuadre
También se permiten las comparaciones:
Integer a = 5; int b = 6;if (a == b) System.out.println(“Iguales”);
El envolvente Boolean se favorece de esta nueva funcionalidad. Antes no podía participar en condiciones, pero ahora si:
Boolean a = true; boolean b = false;Boolean c = a && b;
95
Autoencuadre / Autodesencuadre
El autoencuadre y autodesencuadre también ocurre cuando se pasa un argumento a un método o cuando un método devuelve un valor.public class Autoencuadre {// Este método tiene un parámetro Integer
static void m(Integer v){ System.out.println(“m() recibió ” + v); }// Este método devuelve un int
static int m2(){ return 10; }// Este método devuelve un Integer
static Integer m2(){ return 99; }}
96
Autoencuadre y métodos
// Uso de autoencuadre y autodesencuadrepublic static void main(String args[])// Pasa un int a m(). El valor se autoencuadra a Integer
m(100);
// El objeto iOb recibe el valor int devuelto por m2() Integer iOb = m2(); System.out.println(“m2() devuelve ” + iOb);
// Llamamos a m3(). Devuelve un valor Integer int i = m3(); System.out.println(“m3() devuelve” + iOb);
/* Llamamos a Math.sqrt() con iOb. Este se autoencuadra y su valor se convierte a double */
iOb = 100; System.out.println(“Raiz cuadrada de iOb es” +
Math.sqrt(iOb));}
98
En su forma más simple, una enumeración es una lista de constantes con nombre que definen un nuevo tipo de dato
Un objeto de tipo enumeración puede contener sólo un número de valores fijo definidos por la lista.
Fundamento de la enumeraciones
Una enumeración se crea usando la palabra clave enum.
Ejemplo:
enum DiaSemana {LUNES, MARTES, MIERCOLES,JUEVES, VIERNES, SABADO, DOMINGO }
• Los identificadores LUNES, MARTES, etc., son constantes de enumeración. Cada una se declara como un miembro publico y estático de DiaSemana.
• El tipo de las constantes de enumeración es del tipo de enumeración en el que están declaradas, en este caso del tipo DiaSemana.
99
Fundamento de la enumeraciones
Una vez definida una enumeración se pueden declarar variables de ese tipo. Sin embargo, aunque las enumeraciones definen un tipo de clase, no es necesario crear una instancia de enum con new.
DiaSemana td; // declara una variable de tipo DiasSemana Para asignar un valor de la enumeración a esta variable
heremos:
td = DiaSemana.MARTES; // Asignamos el valor MARTES Para comparar dos constantes de enumeración usamos el
operador ==.
if (td == DiaSemana.LUNES){ . . .
}
Switch (td) { case LUNES: . . . case MARTES: . . . . . .
100
Los métodos values() y valueOf()
Las enumeraciones tienen dos métodos predefinidos: values() y valueOf().
public static tipo_enum[] values()
public static tipo_enum[] valueOf(String cad)
El método values() devuelve un array que contiene una lista con los valores de las constantes de la enumeración.
El método valuesOf() devuelve una constante de enumeración cuyo valor corresponde con la cadena pasada en cad.
101
Los métodos values() y valueOf()
// Creamos una clase Enumeración como cualquier otra claseenum Transporte{ COCHE, CAMION, AVION, TREN, BARCO;}
Ejemplo:
public class EnumDemo{ public static void main(String args[]){
Transporte tp; // declaramos una variable para la enumeraciónSystem.out.println (“Todas las constantes de transporte”);
// uso de values for (Transporte t : Transporte.values())
System.out.println(t);System.out.println();
// uso de valueOf()tp = Trnasporte.valueOf(“AVION”);
System.out.println(“tp contiene”+ tp); }}
102
Constructores, métodos, variables de instancia y enumeraciones.
Cuando se define un constructor para enum, se llama automáticamente al constructor cuando se declara una variable de ese tipo de enumeración, sin necesidad de usar new.
Cada una de las constantes de enumeración puede llamar a cualquier método definido en la enumeración.
Cada constante de enumeración tiene su propia copia para cualquier variable de instancia definida para la enumeración.
Java implementa las enumeraciones como un tipo de clase. Por lo tanto, una enumeración puede incluir constructores, métodos y variables de instancia.
Una enumeración no puede heredar de otra clase, ni ser una superclase. Lo que significa que no puede extenderse.
103
Constructores, métodos, variables de instancia en las enumeraciones.
/* Uso de un constructor, una variable de instancia y un método en una enumeración */
enum Transporte{/* Entre paréntesis se asignan los valores de
inicialización de cada constante de enumeración */ COCHE(90), CAMION(75), AVION(60), TREN(100), BARCO(30);
// variable de instancia private int velocidad; // velocidad típica
// ConstructorTransporte(int v) { velocidad = v; }
// Métodoint getVelocidad() { return velocidad}
}
Ejemplo:
104
Constructores, métodos, variables de instancia en las enumeraciones.
Ejemplo:
// Uso de la enumeración
public class EnumDemo2{ public static void main(String args[]){
Transporte tp; // variable enumeración System.out.println (“La velocidad típica de un avión es: ”
+ Transporte.AVION.getVelocidad()+ “km/h”);
System.out.println(“Velocidad de todos los transportes es ”);
for (Transporte t : Transporte.values())
System.out.println(t.getVelocidad() + “km/h”)); }}
105
En el ejemplo anterior, cuando se declara la variable tp en main(), se llama al constructor de Transporte (no es necesario usar new) una vez por cada constante especificada. Colocados entre paréntesis, se especifican los argumentos del constructor después de cada constante:
Estos valores se pasan al parámetro v de Transporte, que luego se asigna a velocidad.
Se llama una vez al constructor por cada constante. Cada constante contiene su propia copia de velocidad. Por lo tento,
podemos obtener la velocidad de un tipo de transporte al llamar a getVelocidad()
Transporte.AVION.getVelocidad()
Constructores, métodos, variables de instancia en las enumeraciones.
COCHE(90),CAMION(75),AVION(60),TREN(100),BARCO(30);
Nota: La lista termina en punto y coma
106
Todas las enumeraciones heredan automáticamente de java.lang.Enum.
Esta clase define varios métodos para todas las enumeraciones: El método ordinal() devuelve un valor que indica la posición de una constante de enumeración en la lista de constantes. Este valor se le llama ordinal. Los valores ordinales empiezan en 0.
final int ordinal()
El método compareTo() compara el valor ordinal de dos constantes de la misma enumeración.
final int compareTo(tipo_enum e)
Tipo_enum es el tipo de enum y e es la constante que se esta comparando con la constante que se invoca. Si esta tiene un valor ordinal igual que e, comapareTo devuelve cero, en caso contrario devuelve un valor positivo.
Las enumeraciones heredan de Enum.
108
La definición de todas las clases Java la podemos encontrar en la siguiente dirección Web, correspondiente a la documentación de la biblioteca de Java:http://java.sun.com/j2se/1.5.0/docs/api/allclasses-
noframe.html
Todas las clases de java
Definición de la clase System
109
Se trata de una clase con utilidades genéricas del sistema.
Todos sus atributos y métodos son estáticos.
Tiene tres atributos muy utilizados:
public static final PrintStream out;Representa por defecto al stream de salida en pantalla.
public static final InputStream in;Representa por defecto al stream de entrada del teclado.
public static final PrintStream err;Representa por defecto al stream de salida de errores.
Mas información:http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html#field_detail
La clase System
110
La clase System
Y entre sus métodos más utilizados están:
public static Properties getProperties();Devuelve una instancia de java.util.Properties encapsulando las propiedades del sistema.
public static String getProperty(String key);Devuelve el valor de la propiedad del sistema key, o null si no existiese.
Otros métodos:
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/System.html#method_detail
public static long currentTimeMillis();Devuelve la diferencia de entre la hora actual y la medianoche del 1 de enero de 1970 en milisegundos.
public static long nanoTime();Devuelve la hora actual en nanosegundos.
public static void exit(int status);Termina la ejecución de la JVM devolviendo status como código de retorno (cero significa que todo ha ido bien).
111
La clase System
public class SystemTest {public static void main(String[] args){
System.out.println(System.currentTimeMillis());System.out.println(System.nanoTime());System.out.println (System.getProperty("java.runtime.name"));System.out.println(System.getProperties());System.exit(0);System.out.println("Aquí nunca llega.");
}}
Ejemplo:
112
La clase Math
La clase Math proporciona métodos estáticos para realizar operaciones matemáticas, trigonométricas, raíces cuadradas , potencias, etc. Así como las constantes PI y E.
Algunos métodos de la clase Math
abs(n) Valor absoluto de un número
double acos(double n) Arco coseno de un triangulo en radianes
double asin(double n) Arco seno de un triangulo en radianes
double atan(double n) Arco tangente entre –PI/2 y PI/2
double atan2(double n) Arco tangente entre –PI y PI
double ceil(double n) Entero más cercano por encima de n
double floor(double n) Entero más cercano por debajo de n
round(n) Entero más cercano a n
double rint(double n) Entero más próximo a un numero double
113
La clase Math
Algunos métodos de la clase Mathdouble cos(double n) Coseno de un ángulo en radianes
double sin(double n) Seno de un ángulo en radianes
double tan(double n) Tangente de un ángulo en radianes
double exp(double n) Exponencial de n
double log(double n) Logaritmo natural en base e de n
max(a,b) Máximo entre dos valores
min(a,b) Mínimo dos valores
double random() Números aleatorios entre 0 y 1
double pow(double a, double b) Potencia de a elevado b
double sqrt(double n) Raíz cuadrada de n
double toDegrees(double n) Pasa de radianes a grados
double toRadians(double n) Pasa de grados a radianes
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Math.html
Otros métodos:
114
La clase Math
public class MathDemo1{
public static void main(){
Scanner ac = new Scanner(System.in);
System.out.print(“Introduce una cantidad con decimales: ”);
double cantidad = sc.nextDouble();
System.out.print(“Valor inicial: “ + cantidad);
System.out.print(“Valor absoluto: “ + Math.abs(cantidad));
System.out.print(“Aproximación superior: “ + Math.ceil(cantidad));
System.out.print(“Aproximación inferior: “ + Math.floor(cantidad));
System.out.print(“Aproximación más cercana: “ + Math.rint(cantidad));
}
}
Ejemplo 1:
115
La clase Math
publica class MathDemo2{
public static void main(){
Scanner ac = new Scanner(System.in);
System.out.print(“Introduce un cantidad entera: ”);
int base = sc.nextInt();
System.out.println(“Raíz cuadrada: ” + Math.sqrt(base));
double expo = sc.nextDouble();
System.out.print(“Introduce otra cantidad: ”);
System.out.print(cantidad + “Elevado a ” + expo + “ = ” + Math.pow(base, expo));
}
}
Ejemplo 2:
116
La clase Random
La clase Random crea objetos que generan números aleatorios.
Métodos de la clase Random
Int nextInt() Genera números enteros aleatorios positivos y negativos
Int nextInt(int n) Genera números enteros int aleatorios entre 0 y n
long nextLong() Genera números enteros long aleatorios positivos y negativos
flaot nextFloat() Genera números en coma flotante Float aleatorios positivos y negativos
double nextDouble() Genera números en coma flotante Double aleatorios positivos y negativos
boolean nextBoolean() Genera valores booleanos true y false aleatorios
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Random.html
Otros métodos:
117
La clase Random
// Genera números enteros aleatorios entre 0 y 100
public class EnterosAleatorios {
public static void main(){
Random aleatorio = new Random(); //crea un objeto Random
System.out.println(“Diez números aleatorios ”);
for (int i = 0; i < 10; i++) {
// Genera un número aleatorio entero entre 0 y 100
System.out.println(aleatorio.nextInt(100));
}
}
}
Ejemplo:
118
La clase StringBuffer
StringBuffer es otra clase relacionada con las cadenas de caracteres. Pero estas no son inmutables, por lo tanto, se pueden modificar sus caracteres.
Existen distintas formas de crear un StringBuffer:
• Mediante su constructor por defecto:
StringBuffer s = new StringBuffer(); // Se inicializa a “”.
• Mediante su constructor con un parámetro de tipo int:
StringBuffer s = new StringBuffer(3); // Capacidad inicial 3.
• Mediante su constructor con un parámetro de tipo String:
StringBuffer s = new StringBuffer(“Hola”);
119
La clase StringBuffer
.
Para la clase StringBuffer, la primera posición de la cadena de caracteres es la cero (no la uno).
Alguno de sus métodos:
public int indexOf(int ch);Devuelve la primera ocurrencia de ch (-1 si no está).
public StringBuffer append(char c);Añade el carácter c al valor del StringBuffer. Este
métodoestá sobrecargado varias veces recibiendo comoparámetro otros tipos: String, Object, int, float,
long…
public char charAt(int index);Devuelve el carácter de la posición index
120
La clase StringBuffer
.
public int length();Devuelve la longitud de la cadena de caracteres.
public String toString();Devuelve un String representado por el StringBuffer.
public StringBuffer reverse();Devuelve la cadena invertida.
public int capacity();Devuelve el número de caracteres que puede contener
sin necesidad de alocar mas memoria.
public String substring(int beginIndex);Devuelve un String desde beginIndex hasta el final.
Algunos de sus métodos
121
La clase StringBuffer
.
Algunos de sus métodospublic StringBuffer replace(int start, int end, String str);
Reemplaza la cadena entre start y end con str.
public StringBuffer insert(int offset, char c);Inserta c en la posición offset de la cadena. Este método está sobrecargado varias veces recibiendo como parámetro a insertar otros tipos: int, float, long…
public StringBuffer delete(int start, int end);Elimina de los caracteres entre las posiciones start y end.
public void setCharAt(int index, char ch);Reemplaza el carácter de la posición index por ch.
Otros métodos: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuffer.html#method_detail
122
La clase StringBuffer
.
Ejemplo:
public class StringBufferTest{public static void main(String[] args){
StringBuffer sb1 = new StringBuffer("abababab");
System.out.println(sb1.length());System.out.println(sb1.capacity());sb1.setCharAt(sb1.length()-1,'B');System.out.println(sb1);sb1.replace(2,3,"AB");System.out.println(sb1);sb1.insert(4,"CD");System.out.println(sb1);sb1.delete(0,2);System.out.println(sb1);
}}
123
La clase StringBuffer
.
Ejemplo:
public class StringBufferTest {public static void main(String[] args){
StringBuffer sb2 = new StringBuffer(2);System.out.println(sb2.length());System.out.println(sb2.capacity());
for(int i=0; i<10; i++) sb2.append(i);
System.out.println(sb2.length());System.out.println(sb2.capacity());System.out.println(sb2);
}}
124
La clase StringBuffer
.
El uso mas habitual es la creación de Strings cuyo valor se calcula de forma dinámica.
Al no ser inmutable, permite la creación del String final sin otros objetos intermedios que consumirán memoria de forma innecesaria.
Por ejemplo:
StringBuffer tmp = new StringBuffer(10);for (int i=0; i <10; i++)
tmp.append(i);String s = tmp.toString();
Esta vez solo se han creado 2 objetos en memoria:un StringBuffer (el GC puede limpiarlo) y un String.
125
La clase StringBuilder
.
J2SE 5.0 añade la clase StringBuilder al tratamiento de cadenas de caracteres.
Su funcionalidad (constructores y métodos) es idéntica a la de StringBuffer.
La única diferencia es que sus métodos no están sincronizados (veremos qué significa esto en el capítulo de threads).
Tiene mejor rendimiento que StringBuffer.
Mas información:
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html
126
La clase StringBuilder
.
public class StringBuilderTest {public static void main(String[] args){
StringBuilder sb = new StringBuilder("0");System.out.println(sb.length());System.out.println(sb.capacity());for(int i=1; i<10; i++)
sb.append(i);System.out.println(sb.length());System.out.println(sb.capacity());System.out.println(sb);
}}
Ejemplo:
127
La clase StringBuilder
.
public class StringBuilderTest {public static void main(String[] args){
StringBuilder sb = new StringBuilder("0");System.out.println(sb.length());System.out.println(sb.capacity());for(int i=1; i<10; i++)
sb.append(i);System.out.println(sb.length());System.out.println(sb.capacity());System.out.println(sb);
}}
Ejemplo:
128
La clase Date y GregorianCalendar
La clase Date de Java permite crear objetos que informan de la fecha y hora del sistema. Para ver sus métodos consultar:
Las clases Calendar y GregorianCalendar permiten crear objetos que pueden gestionar fechas y tiempos.
Métodos de gregorianCalendar
setTime Asigna a un objeto GregorianCalendar, un objeto de la clase Date, con los datos e la fecha y hora del sistema
set Asigna una fecha cualquiera a un objeto GregorianCalendar
get Obtiene el día de la semana , mes, año, horas, minutos y segundos de un objeto GregorianCalendar
getTimeZone Obtiene la franja horaria de un objeto GregorianCalendar
http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Date.html
http://java.sun.com/j2se/1.4.2/docs/api/java/util/GregorianCalendar.html
129
La clase Date y GregorianCalendar
Algunos atributos (constantes) de la clase Calendar
Calendar.DAY_OF_WEEK Número de día de la semana: 1 a 7
Calendar.DAY_OF_MONTH Día del mes: 1 a 31
Calendar.MONTH Número del Mes: 1 a 12
Calendar.YEAR Año
Calendar.HOUR Hora
Calendar.MINUTE Minutos
Calendar.SECOND Segundos
Métodos de la clase Calendar
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html
130
La clase Date y GregorianCalendar
public class Fechas {
public static void main(){
Date hoy = new Date(); // creamos un objeto fecha
// creamos un objeto gc de la clase GregorianCalendar
GregorianCalendar gc = new GregorianCalendar()
gc.setTime(hoy); // Asignamos a gc la fecha y hora actual
System.out.print(“Hoy es: ”);
System.out.print(gc.get(Calendar.DAY_OF_MONTH) + “-”);
System.out.print(cg.get(Calendar.MONTH) + “-”);
System.out.print(gc.get(Calendar.MONTH) + “-”);
System.out.print(gc.get(Calendar.YEAR) + “ a las ”);
System.out.print(gc.get(Calendar.HOUR) + “:”);
System.out.print(gc.get(Calendar.MINUTE) + “:”);
System.out.print(gc.get(Calendar.SECOND) );
}
} La salida es:Hoy es: 4-6-2007 a las 5:40:42
131
Clases DateFormat y SimpleDate Format
DateFormat es una clase que pertenece al paquete java.text y no al paquete java.util, como las vistas anteriormente.
La razón es para facilitar todo lo referente a la internacionalización, que es un aspecto muy importante en relación con la conversión, que permite dar formato a fechas y horas de acuerdo con distintos criterios locales, como el idioma y el país.
Esta clase dispone de métodos static para convertir Strings representando fechas y horas en objetos de la clase Date, y viceversa.
La clase SimpleDateFormat es la única clase derivada de DateFormat. Es la clase que conviene utilizar. Esta clase se utiliza de la siguiente forma: se le pasa al constructor un String con el formato que se desea utilizar.
132
La clase Date y GregorianCalendar
//* Este programa muestra como se puede formatear una fecha según las características de regionalización instaladas en el ordenador. El objeto formatoFecha de la clase DateFormat obtiene las propiedades de datos numéricos y de fecha del sistema y aplica este estilo al dato fecha obtenido con el objeto hoy de la clase Date. */
public class Fechas2 {
public static void main(){
Date hoy = new Date(); // creamos un objeto fecha
DateFormat formatoFecha = DateFormat.getDateInstance();
String fechaLocal = formatoFecha.format(hoy);
System.out.print(fechaLocal);
}
}
Ejemplo:
134
Gestión de excepciones
Las excepciones permite:
• Encapsular los errores dentro de las clases• Separar el flujo de ejecución normal del tratamiento de errores.
Las excepciones pueden ser tratadas o lanzadas en los programas.
Una excepción es un error que se produce en alguna parte de código durante su ejecución.
135
Jerarquía de clases de excepciones
La clase Throwable describe cualquier clase que pueda ser lanzada como excepción.
Existen dos tipos de clases Throwable: • Error representa errores de compilación y
errores del sistema.• Exception representa excepciones de
tratamiento obligatorio generadas por la aplicación.
Existe un tipo especial de clases Exception:• RuntimeException representa excepciones de
tratamiento NO obligatorio generadas por la aplicación.
136
Jerarquía de clases de excepciones
Error
Object
Throwable
Exception
RuntimeException
Excepciones de tratamiento obligatorio producidas por una aplicación
Excepciones producidas por errores de compilación y del sistema
Todas las clases de excepciones derivan de la clase Throwable
Excepciones de tratamiento NO obligatorio
137
Verificadas (checked):• Su tratamiento es obligatorio y el compilador así lo chequea.• La clase Exception y todas aquellas clases descendientes de esta que no lo sean de RuntimeException
No verificadas (unchecked):• Su tratamiento NO es obligatorio y el compilador no lo chequea.• Todas aquellas clases descendientes de Error o de
RuntimeException
Excepciones verificadas vs. no verificadas
139
Se capturan y manejan mediante los bloques try… catch:
try {
// código que puede generar una excepción
}
catch (ClaseExcepcion e) {
// código de tratamiento de excepción
} . . .
finally {
// código que se ejecutan siempre
}
Captura y manejo de excepciones
Excepción capturada
140
class ExcepcionTratada1 {public static void main ( String args[ ] ) { Scanner teclado = new Scanner(System.in);
try { System.out.print(“Introduce un número: ”); String linea = teclado.nextLine(); int num = Integer.parseInt(linea); System.out.println(“El numero es ” + num);
} catch (NumberFormatException e){ System.out.println(“Error de conversión”); } }}
// Ejemplo1: Tratamiento de una excepción
Captura y manejo de excepciones
141
import java.util.*;class Excepcion2 {
public static void main ( String args[ ] ) { Scanner teclado = new Scanner(System.in);
try { System.out.print(“Introduce un número: ”);
String linea = teclado.nextLine(); int a = Integer.parseInt(linea);
System.out.print(“Introduce otro número: ”); String linea = teclado.nextLine(); int b = Integer.parseInt(linea); System.out.print(“Resultado = ” a/b); }
// Ejemplo2: Tratamiento de varias excepciones en un mismo bloque try .. catch
Captura y manejo de excepciones
catch (NumberFormatException e){ System.out.println(“Error de conversión”); } catch (AritmeticException e) { System.out.println(“División por cero”); } catch (Exception e) System.out.println(“Excepción desconocida”); } }}
142
Las excepción RuntimeException y sus descendientes, son excepciones de tratamiento NO obligatorio (no requieren bloque try .. cath), por lo que si no se gestionan y se produce una de ellas, el programa abortará su ejecución y la maquina virtual java mostrará el mensaje de error correspondiente.
Sin embargo, las excepciones de tratamiento obligatorio, como Exception y sus descendientes (que no lo sean de RuntimeException), requieren obligatoriamente el uso de un bloque try .. catch para capturarlas y tratarlas, y así lo indicará el compilador de Java.
Cuando llamamos a un método de la biblioteca de clases de Java, no sabemos de antemano que tipo de excepción puede generar. Si es de la clase RuntimeException no será necesario tratarla, pero si es de la clase Exception requerirá el uso de un bloque try .. catch; pero, ¿Qué tratamiento le daremos?.
Lanzamiento de excepciones con throw
143
Si un método produce una excepción de la clase Exception (excepciones obligatorias) y NO le damos un tratamiento específico en ese mismo método, debemos especificar esta circunstancia para que los métodos que lo llamen puedan protegerse contra esa excepción.
Esto lo podemos hacer relanzando la excepción usando la cláusula throw en un bloque try .. catch.
Para ello, capturamos la excepción de la clase Exception con un try .. catch y lanzamos una excepción RuntimeException que envuelva a Excepción , pasándole un objeto de esta clase como parámetro:
try {
// código que puede generar la excepción
} catch (Exception e ) { // capturamos la excepción de la clase Exception
// relanzamos la excepción e como una RuntimeException
throw new RuntimeException( e ) ;
}
Lanzamiento de excepciones con throw
144
import java.io.*;class LecturaStringConsola {
public static void main(String args[]){ String cadena; BufferedReader br;
/*Creamos un objeto BufferedReader, para lectura por teclado, usando el constructor de la clase InputStreanReader (usado para flujos de entrada) el usa un objeto System.in (la consola ) un devuelve un objeto de la clase BufferedReader ( un búfer de lectura)*/
br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Empieza a escribir, 'stop' para salir");
do { /* readLine() lee una cadena de caracteres. Puede lanzar una excepción de la clase IOException (tratamiento obligatorio), que es un descendiente de Exception, que requiere el uso de un bloque try .. catch */
cadena = br.readLine(); // OJO!!! Esto no compilará
System.out.println(cadena); } while(!cadena.equals("*"));
}El compilador requerirá que el uso un bloque try.. Catch para tratar la excepción que pueda generarse
Lanzamiento de excepciones con throw
145
import java.io.*; // para la clase BufferedReaderclass LecturaStringConsola {
public static void main(String args[]){ String cadena; BufferedReader br;
/*Creamos un objeto BufferedReader, para lectura por teclado, usando el constructor de la clase InputStreanReader (usado para flujos de entrada) el usa un objeto System.in (la consola ) un devuelve un objeto de la clase BufferedReader ( un búfer de lectura)*/
br = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Empieza a escribir, 'stop' para salir");
//leemos una cadena de caracteres mediante readLine() do {
try{cadena = br.readLine();
System.out.println(cadena); } catch (Exception e){
throw new RuntimeException(e); }
} while(!cadena.equals("*")); }
Lanzamiento de excepciones con throw
En lugar de tratar la excepción, la relanzamos, lanzando una RuntimeException que envuelva la posible excepción de la clase Exception que pueda producirse.